2

This is a follow up to Replace one entire column in one file with a single value from another file combined with R Pass Variable from R to Unix

I am running several scripts (Perl, python and R) in one Unix script and need to pass outputs of these scripts to Unix and combine information from different files these scripts create.

I have a working code which is a combination of the above mentioned questions:

The output from the R script called getenergie.R is a filename. There are several such filenames which are returned and I need to write into each of these files and replace column 11 of these files with a value which comes from another file (COP1A_report1) and is called value.

RES=($(./../getenergies.R))
for pdbnames in "${RES[@]}"
do

#write the one value from COP1A_report1 into column 11 of a file and save as TESTING

value=$(awk -F, 'NR==1{print $2;exit}' ./../COP1A_report1) 
awk '{$11 = v} 1' v="$value" ${pdbnames} > TESTING

printf "$value ${pdbnames}\n"
done

What I need is a way to loop over this so that it writes one value from COP1A_report1 (row $2, line 1) into column 11 of a file called like the first filename stored in $pdbnames, save it as a unique file and go to COP1A_report1 (row $2, line 2), write that into column 11 of a file called like the second filename stored in $pdbnames and so on...

What is the smartest way of doing that? I can imagine something like the code below, but something is wrong with the syntax and I do not get any errors, just an empty value variable.

Any ideas?

counter=1
RES=($(./../getenergies.R))
for pdbnames in "${RES[@]}"
do

value=$(awk -F, 'NR==$counter{print $2;exit}' ./../COP1A_report1) #NR=1 needs to be changed to go through the entire list...
awk '{$11 = v} 1' v="$value" ${pdbnames} > TESTING$counter
counter=$(echo $counter+1 |bc)
printf "$value ${pdbnames}\n"
done
0

You're trying to pass $counter into the awk script, so you need to use double-quotes rather than single-quotes. Single-quotes are for literal strings, double-quotes are for strings with variables in them.

Because you're using double-quotes here, that means you have to escape $2 as \$2 in the awk script so that the shell doesn't substitute it's second arg (if any, empty string otherwise) into the awk script.

value=$(awk -F, "NR==$counter{print \$2;exit}" ./../COP1A_report1

You should also quote other variables when you use them. e.g. awk ... > "TESTING$counter" - lack of quotes was harmless in this instance, but always quoting your variables is a good habit to get into.

Same for counter=$(echo "$counter"+1 |bc) - not quoting is harmless here, but still bad practice.

Finally, you're missing the -v from the awk command when you set v="$value". should be -v v="$value"

counter=1
RES=($(./../getenergies.R))
for pdbnames in "${RES[@]}"
do

    value=$(awk -F, "NR==$counter{print \$2;exit}" ./../COP1A_report1)
    awk -v v="$value" '{$11 = v} 1' "$pdbnames" > "TESTING$counter"
    counter=$(echo "$counter"+1 |bc)
    printf "$value $pdbnames\n"

done
  • Ok. this works. I realise this is a bit off topic, but can you recommend a good blog/book etc on more good practices in unix programming? I would like to avoid the "don't s" in the future, wherever possible... – gugy Oct 28 '15 at 8:50
  • can't recommend a book, but there's lots of good examples here. Look especially for answers by Stéphane Chazelas and Gilles....they really know their stuff and generally provide exceptionally well written and detailed answers. unix.stackexchange.com/users/22565/st%C3%A9phane-chazelas and unix.stackexchange.com/users/885/gilles – cas Oct 28 '15 at 8:53

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.