从脚本运行 awk 时出现错误

从脚本运行 awk 时出现错误

我有一个文件 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

现在,我希望如果当前目录中的文件名存在于上述文件中,则将一个新列添加到具有“FOUND”的该行。例如:如果 awktest.sh 存在于 pwd 中。那么输出结果是:

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

我已经写了这个脚本(在你的帮助下,谢谢)

 #!/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

但输出文件中没有添加新的列。(pwd 中有一些文件存在于 some.txt 中

答案1

代码非常复杂。例如

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

为什么要这样做ls -l,然后提取$9(文件名 - 但请注意,这仅在文件名中没有空格的情况下才有效);而不是仅仅

for fn in *

然后你grep对行号和awk字段提取进行一些操作

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

但为什么不简单地让awk匹配

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

最后,不要通过引用在 shell 和 awk 之间来回切换

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

干净地传递变量作为参数,如

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


现在把这些部分放在一起:

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

不太确定这是否正是您想要的,但它的代码更清晰,至少应该有更少的问题。
现在,通过这种重组,您似乎可以在一个awk实例中完成所有这一切。 (但我把它留给读者作为练习。)

答案2

可以很容易地完成sed

#!/bin/bash
unset pattern
for fn in *
do
    pattern=${pattern:+${pattern}\\|}$f
done
sed -i "/$pattern/s/$/ Found/" some.txt

答案3

!/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

可能还有别的事,但我还没喝咖啡。

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

答案4

您的脚本中的问题:

  • SC2006- 使用 $(..) 代替传统的 `..`。
  • SC2012- 使用 find 而不是 ls 可以更好地处理非字母数字文件名。
  • SC1035- ! 后面缺少一个必需的空格。

    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
    

来源

相关内容