複数のテキストファイル入力をgrepし、ファイルごとに異なる出力を生成します。

複数のテキストファイル入力をgrepし、ファイルごとに異なる出力を生成します。

ループでgrepとawkを使用して複数のテキストファイルをフィルタリングするスクリプトがあります。フィルタリング後に各ファイルの出力を生成すると問題が発生します。

これは私のスクリプトです。

grep_multi.sh

path=$(find /home/folder/file/source -iname "Tracert*" )

for i in "$path"
do
        grep -E '^%%.*.%%$'\|'IPv4 type' $i | awk '/%%TRACERT:/ {sfx = $0; next} {print $1","$2","$3","$4","$5","$6","$7" "$8","sfx}' > filter.result.$i 

done

スクリプトを実行すると、私は得ます。間違いこのように:

./grep_multi.sh: line 5: filter.result.$i: ambiguous redirect

これは変数 $path

$ find /home/folder/file/source -iname "Tracert*"
/home/folder/file/source/Tracert_1.txt
/home/folder/file/source/Tracert_2.txt
/home/folder/file/source/Tracert_3.txt
/home/folder/file/source/Tracert_4.txt
/home/folder/file/source/Tracert_5.txt
/home/folder/file/source/Tracert_6.txt
/home/folder/file/source/Tracert_7.txt
/home/folder/file/source/Tracert_8.txt

tracert_1.txt

O&M    #108
%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
RETCODE = 0  Operation succeeded

The result is as follows
------------------------
 Record index  Response number  First response time(ms)  Second response time(ms)  Third response time(ms)  IP type    Peer IP address

 1             3                1                        1                         1                        IPv4 type  10.10.10.10    
 2             3                1                        1                         1                        IPv4 type  10.10.10.10  
 3             0                NULL                     NULL                      NULL                     IPv4 type  Timeout        
 4             0                NULL                     NULL                      NULL                     IPv4 type  Timeout        
 5             3                1                        1                         1                        IPv4 type  10.10.10.10   
 6             3                1                        1                         1                        IPv4 type  10.10.10.10   
 7             3                1                        1                         1                        IPv4 type  10.10.10.10   

ベストアンサー1

変数を参照すると、"$path"ループは一度実行され、$iフルパスリストに展開されます。これにより、リダイレクトが次のように表示されます。

> filter.result./home/folder/file/source/Tracert_1.txt /home/folder/file/source/Tracert_2.txt ...

これは「あいまいだ」。このやや関連する質問を見ました。検索結果を繰り返すのはなぜ悪い習慣ですか?


実際にはシェルループは必要なく、必要もありませんgrepIPv4次のコマンドを使用して行を選択し、現在のすべての行から名前付きファイルにリダイレクトできます。FILENAMEawk

awk '
  /%%TRACERT:/ {sfx = $0; next} 
  /IPv4 type/ {print $1","$2","$3","$4","$5","$6","$7" "$8","sfx > "filter.result." FILENAME}
' tracert_*.txt

~のため地元のファイルを生成すると、次のような出力が生成されます。

$ head filter.result*
==> filter.result.tracert_1.txt <==
1,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
2,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
3,0,NULL,NULL,NULL,IPv4,type Timeout,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
4,0,NULL,NULL,NULL,IPv4,type Timeout,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
5,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
6,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
7,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%

==> filter.result.tracert_2.txt <==
1,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
2,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
3,0,NULL,NULL,NULL,IPv4,type Timeout,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
4,0,NULL,NULL,NULL,IPv4,type Timeout,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
5,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
6,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%
7,3,1,1,1,IPv4,type 10.10.10.10,%%TRACERT: IPTYPE=IPv4, LOCALIP4="10.10.10.10", PEERIP4="10.10.10.10", MAXHOP=15;%%

で使用するには、find次のことができます。

find /home/folder/file/source -iname "Tracert*" -execdir awk '
      /%%TRACERT:/ {sfx = $0; outfile = "filter.result." substr(FILENAME,3); next} 
      /IPv4 type/ {print $1","$2","$3","$4","$5","$6","$7" "$8","sfx > outfile}
' {} +

これにより、出力ファイルが入力ファイルと同じディレクトリに配置されます。ファイルが実際に単一のディレクトリにある場合は、cdそのディレクトリで "local" awk コマンドを使用する方が簡単です。

おすすめ記事