루프에서 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 ...
이것은 "모호하다". 이 다소 관련된 질문을 보았습니다.찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?
실제로 쉘 루프가 필요하지 않으며 필요하지도 않습니다 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 명령을 사용하는 것이 더 간단합니다.