Help required to Print Single quote into a file

Hi,

I need help in printing string enclosed with single quotes to a file.

I am trying to write a shell script which when run will create another script below is the script logic.

cat create_script.sh
echo '#!/bin/sh' > append_flname.sh
echo 'for FILE in $*' >> append_flname.sh
echo 'do'	>> append_flname.sh
echo '/bin/awk ''{$0 = FILENAME "|" $0; print}'' $FILE' >> append_flname.sh
echo 'done' >> append_flname.sh

The problem is the script created (append_flname.sh) when create_script.sh is run does not have single quotes include for awk command.

The body has:

/bin/awk {$0 = FILENAME "|" $0; print} $FILE

but required is
The body has:

/bin/awk '{$0 = FILENAME "|" $0; print}' $FILE

I have tried many combination using \ or " but none of them succeeded. Please advise.

Thanks,
Imran.

Try

echo "/bin/awk '{$0 = FILENAME \"|\" $0; print}' \$FILE"

or

echo '/bin/awk '\''{$0 = FILENAME "|" $0; print}'\'' $FILE'
1 Like

Hello imrandec85,

Could you please try following and let me know if this helps.

cat script.ksh
awk -vs1="'" -vs2="\"" 'BEGIN{print "#!/bin/sh" ORS "for FILE in $*" ORS "do" ORS "awk  " s1 "{$0 = FILENAME " s2 "|" s2 "$0; print}" s1 " $FILE" ORS "done" >> "append_flname.sh"}' | sh
chmod 755 append_flname.sh
./append_flname.sh   Input_file1     Input_file2

EDIT: Adding a single awk script/code which will do your task of creating the script and running it too as follows.

awk -vs1="'" -vs2="\""  -vs3="\\" 'BEGIN{print "awk -vs1=" s2 s1 s2 " -vs2=" s2 s3 s2 s2 OFS s1 "BEGIN{print " s2 "#!/bin/sh" s2 " ORS " s2 " for FILE in $*" s2 "ORS " s2 "do" s2 "ORS " s2 "awk  " s2 " s1 " s2 "{$0 = FILENAME " s2 "s2 " s2 "|" s2 " s2 " s2 "$0; print}"  s2 "s1 " s2 " $FILE" s2 " ORS " s2 "done" s2 ">> " s2 "append_flname.sh" s2 "}" s1 " | sh" ORS "chmod 755 append_flname.sh" ORS "./append_flname.sh  Input_file1  Input_file2"}' | sh

Also one liner command form of above awk command is as follows.

awk -vs1="'" -vs2="\""  -vs3="\\" 'BEGIN{
                                          print "awk -vs1=" s2 s1 s2 " -vs2=" \
                                          s2 s3 s2 s2 OFS s1 \
                                          "BEGIN{print " s2 "#!/bin/sh" s2 " ORS " s2 \
                                          " for FILE in $*"  \
                                          s2 "ORS " s2 "do" s2 "ORS " s2 "awk  " s2 " s1 " \
                                          s2 "{$0 = FILENAME " s2 "s2 " s2 "|" s2 " s2 " s2 "$0; print}"  \
                                          s2 "s1 " s2 " $FILE" s2 " ORS " s2 "done" s2 ">> " s2 "append_flname.sh"  \
                                          s2 "}" s1 " | sh" ORS "chmod 755 append_flname.sh" ORS "./append_flname.sh  Input_file1  Input_file2"
                                         }
                                   '  | sh

You need to provide Input_file names as above shown Input_file1 and Input_file2 , like that you could give all Input_file names and could run the script. Please try this and let us know how it goes then.

Thanks,
R. Singh

Try:-

echo '	/bin/awk '\''{$0 = FILENAME "|" $0; print}'\'' $FILE' >> /tmp/append_flname.sh
1 Like

Thanks RudiC & wisecracker. Solution provided by both of you worked for me.

RavinderSingh13, I was facing some other issue using commands provided.
Problem: The cursor is moving to next line [>] expecting some other commands i guess, anyways thank you for the response.

Hello imrandec85,

I have used following one-liner solution and it worked for me.

awk -vs1="'" -vs2="\""  -vs3="\\" 'BEGIN{
                                          print "awk -vs1=" s2 s1 s2 " -vs2=" \
                                          s2 s3 s2 s2 OFS s1 \
                                          "BEGIN{print " s2 "#!/bin/sh" s2 " ORS " s2 \
                                          " for FILE in $*"  \
                                          s2 "ORS " s2 "do" s2 "ORS " s2 "awk  " s2 " s1 " \
                                          s2 "{$0 = FILENAME " s2 "s2 " s2 "|" s2 " s2 " s2 "$0; print}"  \
                                          s2 "s1 " s2 " $FILE" s2 " ORS " s2 "done" s2 ">> " s2 "append_flname.sh"  \
                                          s2 "}" s1 " | sh" ORS "chmod 755 append_flname.sh" ORS "./append_flname.sh  Input_file1  Input_fil2"
                                         }
                                   '  | sh

EDIT: Checked non-one liner in my previous post and both solutions are working as expected as follows.

awk -vs1="'" -vs2="\""  -vs3="\\" 'BEGIN{print "awk -vs1=" s2 s1 s2 " -vs2=" s2 s3 s2 s2 OFS s1 "BEGIN{print " s2 "#!/bin/sh" s2 " ORS " s2 " for FILE in $*" s2 "ORS " s2 "do" s2 "ORS " s2 "awk  " s2 " s1 " s2 "{$0 = FILENAME " s2 "s2 " s2 "|" s2 " s2 " s2 "$0; print}"  s2 "s1 " s2 " $FILE" s2 " ORS " s2 "done" s2 ">> " s2 "append_flname.sh" s2 "}" s1 " | sh" ORS "chmod 755 append_flname.sh" ORS "./append_flname.sh Input_file1  Input_file2"}' | sh

Output came as follows.

Input_file1|                      03/08/2016 09:40-09:45            4       0.0
Input_file1|*********                        ------------ ---------
Input_file2|test|chumma_test
Input_file2|test|chumma_test11

Thanks,
R. Singh

For a literal transfer of text from a script to a file, I think the best method would be the quoted here-document:

cat << "EOF" >> append_flname.sh
#!/bin/sh
for FILE in $*
do
  /bin/awk '{$0 = FILENAME "|" $0; print}' "$FILE"
done
EOF 

Which literally puts the content in the file, without worries of quotes, escapes, globbing or variable expansions..

1 Like