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
ただし、出力ファイルには新しい列は追加されません。 (some.txtに存在するpwdファイルがいくつかあります。)
答え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 )
最後に、引用符を使用してシェルとawkの間を前後に切り替えないでください。
>> awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
変数を次の引数にきちんと渡します。
awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1'
次に、次の部分を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– 英数字以外のファイル名を処理するには、ls の代わりに find を使用します。
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