user5420138
user5420138

Reputation: 131

awk script to read input file with different number of fields in each line

Input file has different number of fields in each line.

Is there any way to get the expected output with awk?

awk -F',' '{print "echo "$1; for (i = 2; i <= NF; i++) print "command1 "$i " command2"}' test.txt

test.txt

"abc",4,21,22,25
"standard",1 
"test",4,5,10,11,12

Output:

echo "abc"
command1 4 command2
command1 21 command2
command1 22 command2
command1 25 command2
echo "standard"
command1 1 command2
echo "test"
command1 4 command2
command1 5 command2
command1 10 command2
command1 11 command2
command1 12 command2

Expected Output:

echo "abc" command1 4 command2
echo "abc" command1 21 command2
echo "abc" command1 22 command2
echo "abc" command1 25 command2
echo "standard" command1 1 command2
echo "test" command1 4 command2
echo "test" command1 5 command2
echo "test" command1 10 command2
echo "test" command1 11 command2
echo "test" command1 12 command2

Upvotes: 1

Views: 117

Answers (3)

Tyl
Tyl

Reputation: 5252

Please try this:

awk -F, '{for (i=2;i<=NF;i++) print "echo", $1, "command1", $i, "command2"}'

Eg:

$ cat file
"abc",4,21,22,25
"standard",1
"test",4,5,10,11,12

$ awk -F, '{for (i=2;i<=NF;i++) print "echo", $1, "command1", $i, "command2"}' file
echo "abc" command1 4 command2
echo "abc" command1 21 command2
echo "abc" command1 22 command2
echo "abc" command1 25 command2
echo "standard" command1 1  command2
echo "test" command1 4 command2
echo "test" command1 5 command2
echo "test" command1 10 command2
echo "test" command1 11 command2
echo "test" command1 12 command2

Default OFS is a space, so I just use commas to separate different things which needed to print.

For fun, GNU sed solution:

sed -r '/,/!d;/,/{s/([^,]*),([^,]*)/"echo" \1 "command1" \2 "command2"\n\1/; P; D;}'

Another noloop awk approach similar to RavinderSingh13's answer, but concise:

awk -F, '{gsub(/,/,"\necho " $1 " command1 ");sub(/[^\n]*\n/,"");gsub(/\n|$/," command2\n");printf $0}' file

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133458

A diferent approach without using loops here.

awk -F, '
/^\"/ && prev{
  print prev
  prev=""
}
{
  gsub(/,/,"\necho "  $1  " command1 ")
}
{
  gsub(/$/," command2")
  prev=$0
  sub(/.*\"\n/,"",prev)
  gsub(/\n/," command2\n",prev)
}
END{
  if(prev){
    print prev
  }
}'   Input_file

Output will be as follows.

echo "abc" command1 4 command2
echo "abc" command1 21 command2
echo "abc" command1 22 command2
echo "abc" command1 25 command2
echo "standard" command1 1  command2
echo "test" command1 4 command2
echo "test" command1 5 command2
echo "test" command1 10 command2
echo "test" command1 11 command2
echo "test" command1 12 command2

Upvotes: 1

stack0114106
stack0114106

Reputation: 8711

Just put the echo statement inside the for loop

$ awk -F',' '{for (i = 2; i <= NF; i++) print "echo "$1  " command1 "$i " command2"}' test.txt
echo "abc" command1 4 command2
echo "abc" command1 21 command2
echo "abc" command1 22 command2
echo "abc" command1 25 command2
echo "standard" command1 1  command2
echo "test" command1 4 command2
echo "test" command1 5 command2
echo "test" command1 10 command2
echo "test" command1 11 command2
echo "test" command1 12 command2

$

Upvotes: 0

Related Questions