5

I have a csv file looks like this:

site1.com,aaa,bbb,ccc
site2.com,qqq
site3.com,rrr,uuu,ppp
site4.com
site5.com,ddd,sss

I want to replace rows (lines) where the fourth column is empty. and I want to manipulate said rows by running a command on them. For example, with awk:

awk -F, '$4=="" {system("$1,cmd1 $1")}' test.csv

I then want to export as follows (output1 is output from cmd1 command):

site1.com,aaa,bbb,ccc
site2.com,output1
site3.com,rrr,uuu,ppp
site4.com,output1
site5.com,output1
  • cmd1 should be run with the first field as argument, right? – Stéphane Chazelas Dec 13 '16 at 9:43
  • I ignore my own advice occasionally but I strongly advise using a proper table editing tool here instead of awk (my own weapon of choice is R, but there are others, such as csvtool). – Konrad Rudolph Dec 13 '16 at 13:05
1
awk -F, '{ if ( $4 == "" ){printf "%s,",$1 ; system(CMD) ;}else {print $0}}' test.csv

If the fourth filed is empty print the first field with the output of the command, else print the hole line.

But be aware of the output of the command how it will print

5
awk -F, -v q=\' '
  function shellquote(s) {
    gsub(q, q "\\" q q, s)
    return q s q
  }
  $4 == "" {
    printf "%s,", $1
    system("cmd " shellquote($1))
    next
  }
  {print}'

The shellquote part is important. Consider the case of a value of $1 like ;reboot for instance.

1

You could use the following code:

awk -v output1="$(cmd1)" 'BEGIN{FS=OFS=","} NF&&NF<4{print $1,output1}1' file

The option -v set the variable output1 as the result of the shell command cmd1.

The statement BEGIN{FS=OFS=","} is setting the delimiter to the comma.

If the line is not empty and the number of fields is lower than 4, replace the line.

At last, the 1 triggers the default statement in awk: print the whole line.

0

may be this post helps you https://stackoverflow.com/questions/20646819/how-can-i-pass-variables-from-awk-to-a-shell-command

$ cat input.txt
a,b,c,d
a,b
a,b,c,d
a,b,c
a,b,c,d


$ awk -F, 'NF<4{cmd="echo output1";while(cmd|getline line){printf("%s,%s\n",$0,line)};close(cmd);next}1' input.txt
a,b,c,d
a,b,output1
a,b,c,d
a,b,c,output1
a,b,c,d
0
sed -rn '
/\S+,\S+,\S+,\S+/{p;b}      # if all four columns exist, print and branch to end
s/^([^,]+).*/\1/            # else extract first column
h                           # hold
s/.*/echo output &/e        # exeute external command echo with first column as argument
G                           # append previous hold value
s/(.*)\n(.*)/\2,\1/         # arrange position
p' file                     # print result

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.