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