4

I have table in the current format:

Lead:Arrow1:Arrow2:Arrow3
Follow:Arrow4:Arrow5:Arrow6:Arrow7:Arrow8:Arrow9

I want to turn this to the

Lead
Arrow1
Arrow2
Arrow3
Follow
Arrow4
Arrow5
Arrow6
Arrow7
Arrow8
Arrow9

I tried awk:

$(awk -F":" '/Lead/ {print NF-1}' $f)
$(awk -F":" '/Follow/ {print NF-1}' $f)

but it didn't work. How can I do it in awk or any other method?

peterh
  • 9,488
  • 16
  • 59
  • 88
kashef
  • 41
  • 3
  • 3
    Possible duplicate of [Print each field of CSV on newline without knowing number of fields](https://unix.stackexchange.com/questions/386840/print-each-field-of-csv-on-newline-without-knowing-number-of-fields) – αғsнιη Oct 09 '18 at 13:05

3 Answers3

8

You can use tr as follows:

<file tr ":" "\n"

Lead
Arrow1
Arrow2
Arrow3
Follow
Arrow4
Arrow5
Arrow6
Arrow7
Arrow8
Arrow9

or awk as follows:

<file awk '{gsub(/:/,"\n")}1'
Lead
Arrow1
Arrow2
Arrow3
Follow
Arrow4
Arrow5
Arrow6
Arrow7
Arrow8
Arrow9
1

Using awk as you suggested:

$ awk '{ gsub(":", "\n", $0); print }' <file
Lead
Arrow1
Arrow2
Arrow3
Follow
Arrow4
Arrow5
Arrow6
Arrow7
Arrow8
Arrow9

This simply replaces each : in the input data with a newline.


Another awk solution which uses the OFS (Output Field Separator) variable:

awk -v OFS='\n' -F ':' '{ $1=$1; print }' <file

The assignment $1=$1 looks bogus but it forces awk to reformat the current input record according to OFS (and ORS, but we don't change that from the default, which is a newline), which in this case means inserting newlines between all :-delimited fields.


With awk, we could also just iterate over the :-delimited fields and print them individually:

awk -F ':' '{ for (i = 1; i <= NF; ++i) print $i }' <file
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
0

Another super-simple solution would be to convert the :s to spaces with sed, and then print the words with echo in a for loop:

for i in $(sed 's/:/ /g')
do
  echo $i
done

This script works from stdin to stdout.

peterh
  • 9,488
  • 16
  • 59
  • 88