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 ...

这是“模棱两可的”。看到这个有点相关的问题为什么循环查找的输出是不好的做法?


您实际上并不需要 shell 循环 - 而且您也不需要grep。您可以使用IPv4以下命令选择行并重定向到名称源自当前所有行的文件: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 命令会更简单。

相关内容