![grep 多文本文件输入并为每个文件创建不同的输出](https://linux22.com/image/162296/grep%20%E5%A4%9A%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%BE%93%E5%85%A5%E5%B9%B6%E4%B8%BA%E6%AF%8F%E4%B8%AA%E6%96%87%E4%BB%B6%E5%88%9B%E5%BB%BA%E4%B8%8D%E5%90%8C%E7%9A%84%E8%BE%93%E5%87%BA.png)
我有一个脚本,可以在循环中使用 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
以下命令选择行并重定向到名称源自当前所有行的文件:FILENAME
awk
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 命令会更简单。