0

I have a file some.txt

-rwxrw-r-- 1 ivamshky ivamshky    152 Apr  2 00:42 12.sh~
-rw-rw-r-- 1 ivamshky ivamshky     58 Apr  6 19:03 a.c
-rw-rw-r-- 1 ivamshky ivamshky     98 Apr  1 20:27 all.sh
-rwxrwxr-x 1 ivamshky ivamshky   8509 Apr  6 19:04 a.out
-rw-rw-r-- 1 ivamshky ivamshky     46 Apr  6 19:07 a.py
-rw-rw-r-- 1 ivamshky ivamshky    399 Apr 18 00:37 attendance.csv
-rw-rw-r-- 1 ivamshky ivamshky    341 Apr 20 01:08 attendance.sh
-rw-rw-r-- 1 ivamshky ivamshky      0 Apr 19 16:21 awk
-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh

Now, I want that if a filename in current directory is present in above file, then a new coloumn is added to that line having "FOUND". eg: if awktest.sh is present in pwd. then the output comes out to be:

-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh   FOUND

I havve written this script(With your Help, Thanks)

 #!/bin/bash
for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" }1' some.txt >some.out
done

but there's no new coloumn is added in the outputfile.(there are some files in pwd which are present in some.txt

  • You should show exactly what you've done, how you called it, which shell you're using, versions of the tools, and on which platform you are working. – Janis Apr 21 '15 at 18:35
  • Which shell? It works in zsh and bash without any errors. – A.B. Apr 21 '15 at 18:41
  • 1
    It works also in ksh and should work in every POSIX shell. – Janis Apr 21 '15 at 18:42
  • I m also using bash. It works when I run this command on terminal. but doesn't work in a script. – Shivam Apr 21 '15 at 18:43
  • You said already that it fails. - Now, which platform? - Then, how did you call it? – Janis Apr 21 '15 at 18:45
0

Much easy it can be done with sed

#!/bin/bash
unset pattern
for fn in *
do
    pattern=${pattern:+${pattern}\\|}$f
done
sed -i "/$pattern/s/$/ Found/" some.txt
  • Thanks it's working. but, is there any way to do it with awk because I am doing something with a csv file. Above problem is just like testing. Also can you tell me what is the Line "pattern=${pattern:+${pattern}\\|}$fn" doing? – Shivam Apr 21 '15 at 20:06
1

The code is very convoluted. For example

>>  list=$(ls -l | awk 'NR > 1 { print $9;}')
>>  for fn in $list 

Why do you do ls -l but then extract $9 (the filename - but note that this does only work if no whitespace is part of the filename); instead of just

for fn in *

Then you do some grep for line numbers and awk for field extraction

>>  n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'`

but why not simply let awk do the matching

n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )

And finally, instead of switching forth and back between shell and awk by quoting

>>  awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out

pass the variable cleanly as parameter, as in

awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1'


Now putting those pieces together:

for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1' some.txt >some.out
    mv some.out some.txt
done

Not quite sure whether this is exactly what you want, but it's clearer code and should have lesser issues at least.
Now with this restructuring it seems you can do that all also in just one awk instance, it seems. (But I leave that as exercise for the reader.)

0
!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list 
do
echo $fn
    n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'` # change this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    mv some.out some.txt
done



!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list; do # also decided to clean this up
    echo $fn
    n=$(grep -n "$fn" some.txt | awk -F":" '{ print $1;}') # to this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out # also, what is this line supposed to do? There is usually a better way to do something that have to run a mv command to overwrite
    mv some.out some.txt
done

There might be something else, but I haven't had my coffee yet.

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

0

Problems in your script:

  • SC2006 - Use $(..) instead of legacy `..`.
  • SC2012 - Use find instead of ls to better handle non-alphanumeric filenames.
  • SC1035 - You are missing a required space after the !.

    1  !/bin/bash
        ^––SC1035 You are missing a required space after the !.
    2  list=$(ls -l | awk 'NR > 1 { print $9;}')
              ^––SC2012 Use find instead of ls to better handle non-alphanumeric filenames.
    3  for fn in $list 
    4  do
    5  
    6      n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'`
             ^––SC2006 Use $(..) instead of legacy `..`.
    7      awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    8      mv some.out some.txt
    9  done
    

Source

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.