I am trying to use nawk sub to substitute a string in a file. Both the pattern and the replacement I set as variables using bash.
here is the code:
#!/bin/bash -x
ydate=`/usr/local/bin/date +%Y%m%d`
echo $ydate
test_ca=/home/mdadmin/test_ca
for i in `cat ${test_ca}`
do
if [[ $i == *cana* ]]; then
new_f=`/usr/bin/nawk -F"/" -v dt="$ydate" '{ print $5 "." dt }' $test_ca`
echo $new_f
nawk -F "/" -v y=$i,z=$new_f ' { sub(y,z,$4) ; print $0} ' ${test_ca}
fi
done
When I execute it returns
/pub/data/cana/Peoccam
I want it to return :
/pub/data/cana/Peoccam.20140612
Any suggestions are greatly appreciated. I have the bash -x output if needed.
There seems to be a bit of overhead. Why are you processing each line in test_ca then running nawk against it twice. The idea behind nawk is it's a filtering language so you should only have to filter your input file once.
Simplify this and create a nawk file and use the -f option to point to it.
Post your input file test_ca.
I need to execute an mv on the file to rename with the date appended. I removed the mv command from the post for simplicity.
So bascially I need to rename the file and then change the name in the test_ca file so I can sftp it.
here are the contents of test_ca -
/pub/data/cana/Peoccam
Not quite sure what your requirements are without seeing an example input file and output file, but this might get you along the way:
nawk -F/ -v dt=$(/usr/local/bin/date +%Y%m%d) '
/cana/ { v=$5"."dt}
{ $NF=v ; print } ' OFS=/ /home/mdadmin/test_ca
... or even. Remove echo (in read) once your sure it's going to do what you want:
while read filename
do
echo mv $filename $filename.$(/usr/local/bin/data +%Y%m%d)
done < /home/mdadmin/test_ca
1 Like
Thanks. Seeing a different approach does help.
However, do you have any ideas why the sub is not substituing. In the original piece of code I did the following-
nawk -F "/" -v y=$i,z=$new_f ' { sub(y,z,$4) ; print $0} ' ${test_ca}
The Z is -
/pub/data/cana/Peoccam.20140612
the y is
/pub/data/cana/Peoccam
this is the output from shell-
smenago@ftp02$ bash -x test_app
++ /usr/local/bin/date +%Y%m%d
+ ydate=20140612
+ echo 20140612
20140612
+ test_ca=/home/mdadmin/test_ca
++ cat /home/mdadmin/test_ca
+ for i in '`cat ${test_ca}`'
+ [[ /pub/data/cana/Peoccam == *cana* ]]
++ /usr/bin/nawk -F/ -v dt=20140612 '{ print $5 "." dt }' /home/mdadmin/test_ca
+ new_f=Peoccam.20140612
+ echo Peoccam.20140612
Peoccam.20140612
+ mv /pub/data/cana/Peoccam /pub/data/cana/Peoccam.20140612
mv: cannot access /pub/data/cana/Peoccam
+ nawk -F / -v y=/pub/data/cana/Peoccam,z=Peoccam.20140612 ' { sub(y,z,$4) ; print $0} ' /home/mdadmin/test_ca
/pub/data/cana/Peoccam
smenago:
Thanks. Seeing a different approach does help.
However, do you have any ideas why the sub is not substituing. In the original piece of code I did the following-
nawk -F "/" -v y=$i,z=$new_f ' { sub(y,z,$4) ; print $0} ' ${test_ca}
The Z is -
/pub/data/cana/Peoccam.20140612
the y is
/pub/data/cana/Peoccam
this is the output from shell-
smenago@ftp02$ bash -x test_app
++ /usr/local/bin/date +%Y%m%d
+ ydate=20140612
+ echo 20140612
20140612
+ test_ca=/home/mdadmin/test_ca
++ cat /home/mdadmin/test_ca
+ for i in '`cat ${test_ca}`'
+ [[ /pub/data/cana/Peoccam == *cana* ]]
++ /usr/bin/nawk -F/ -v dt=20140612 '{ print $5 "." dt }' /home/mdadmin/test_ca
+ new_f=Peoccam.20140612
+ echo Peoccam.20140612
Peoccam.20140612
+ mv /pub/data/cana/Peoccam /pub/data/cana/Peoccam.20140612
mv: cannot access /pub/data/cana/Peoccam
+ nawk -F / -v y=/pub/data/cana/Peoccam,z=Peoccam.20140612 ' { sub(y,z,$4) ; print $0} ' /home/mdadmin/test_ca
/pub/data/cana/Peoccam
Looks like variable you properly not defined
see difference here in example :
$ awk -vx=1,y=2 'BEGIN{print y}'
$ awk -vx=1,y=2 'BEGIN{print x}'
1,y=2
$ awk -vx=1 -vy=2 'BEGIN{print x,y}'
1 2
1 Like
Also even if you get y and z assigned properly, lets expand out what sub(y,z,$4)
is seeing:
sub("/pub/data/cana/Peoccam", "Peoccam.20140612", "cana")
So substitute "/pub/data/cana/Peoccam" with "Peoccam.20140612" in string "cana"
Thanks for the input. I reassigned correctly and tried to alter the command based on the interpretation of the gsub.
I simplified it to the below.
nawk -F / -vz=Peoccam.20140613 ' { gsub("Peoccam", z,$5) ; print $0} '
However, when I execute the below the return gives the path without the foward slashes -
smenago@sftp02$ bash -x test_app
++ /usr/local/bin/date +%Y%m%d
+ ydate=20140613
+ echo 20140613
20140613
+ test_ca=/home/mdadmin/test_ca
++ cat /home/mdadmin/test_ca
+ for i in '`cat ${test_ca}`'
+ [[ /pub/data/cana/Peoccam == *cana* ]]
++ /usr/bin/nawk -F/ -v dt=20140613 '{ print $5 "." dt }' /home/mdadmin/test_ca
+ new_f=Peoccam.20140613
+ echo Peoccam.20140613
Peoccam.20140613
+ mv /pub/data/cana/Peoccam /pub/data/cana/Peoccam.20140613
mv: cannot access /pub/data/cana/Peoccam
+ echo /pub/data/cana/Peoccam
/pub/data/cana/Peoccam
+ nawk -F / -vz=Peoccam.20140613 ' { gsub("Peoccam", z,$5) ; print $0} ' /home/mdadmin/test_ca
pub data cana
There are two mistakes.
You must also set OFS to / otherwise the modification of $5, causing a rebuild of $0, uses the default OFS (output field separator is a space).
There must be a space between -v and z=
Not important here: gsub tries multiple substitutens, sub is sufficient here.
And there are bugs with brackets if the first argument in sub or gsub is in quotes. Better use slashes as first choice.
nawk -v z="Peoccam.20140613" 'BEGIN {FS=OFS="/"} {gsub(/Peoccam/,z,$5) ; print}' /home/mdadmin/test_ca
1 Like
Yes. Thanks for the help as the explanation helped resolve the issue.
Appreciate the help.