IP 주소와 열린 포트가 포함된 CSV 파일이 있습니다.
IP,1,3,4,6,7,9,13,17,19,20,21,22,23,24,25,26
1.1.1.2,,,,,,,,,,,open,,,,,
1.1.1.3,,,,,,,,,,,open,,,,,
1.1.1.4,,open ,open,,,,,,,,open,,,,,
1.1.1.5,,,,,,,,,,,open,,,,,
1.2.3.4,,,,,,,,,,,open,,,,,
1.4.5.6,,,,,open,,,,,,open,,,,,
1.4.5.6,,,,,,,,,,,open,,,,,
1.1.3.4,,,,,,,,,,,open,,,,,
열린 포트가 있는 각 IP 주소에 대해 IP 주소와 열린 포트의 포트 번호(CSV 헤더에서 가져옴)를 사용하여 명령을 실행해야 합니다.
답변1
이 문제를 해결하다완전히순수하게 접근하는 것은 바람직하지 않다고 생각합니다 bash
. 예를 들어 질문을 참조하세요.쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?".
대신 입력 데이터를 이해하기 쉽게 만들어 보겠습니다.
awk 'FNR == 1 { split($0, port, ","); FS=","; next }
{ for (i=2; i<=NF; ++i) if ($i == "open") print $1, port[i] }' file.csv
이 awk
명령은 먼저 CSV 파일의 첫 번째 줄에 있는 포트 번호를 배열로 읽어옵니다 port
. 해당 열의 포트 번호 N
는 에 저장됩니다 port[N]
.
입력의 첫 번째 줄을 쉼표로 구분하고 결과를 배열에 저장하여 이를 수행합니다 port
. 이것이 split()
명령이 하는 일입니다. 조건은 FNR == 1
"이것이 파일의 첫 번째 줄이면 다음을 수행하십시오..."( FNR
현재 입력 파일의 줄 번호)를 의미합니다. 각 입력 줄에 대해 무조건적인 코드 블록이 실행됩니다.
를 호출 split()
한 후 FS
필드 구분 기호가 쉼표로 설정됩니다. 즉, 파일의 다른 줄은 자동으로 필드로 쉼표로 구분됩니다. 이는 두 번째 블록의 루프에서 각 행의 CSV 필드(두 번째 필드에서 마지막 필드까지)를 반복하는 데 사용됩니다.
데이터의 다른 모든 행에 대해 쉼표로 구분된 필드를 반복하고 값이 string 인 필드를 찾으면 open
IP 주소(첫 번째 필드)와 해당 포트 번호를 인쇄합니다.
질문의 데이터를 고려하면 이 명령의 출력은 다음과 같습니다.
1.1.1.2 21
1.1.1.3 21
1.1.1.4 4
1.1.1.4 21
1.1.1.5 21
1.2.3.4 21
1.4.5.6 7
1.4.5.6 21
1.4.5.6 21
1.1.3.4 21
이는 셸의 루프를 통해 쉽게 읽을 수 있습니다.
while read -r ip port; do
telnet "$ip" "$port" # or whatever your command is
done
그러면 IP 주소와 포트 번호가 하나씩 읽혀집니다.
이를 완전한 스크립트로 결합하려면 다음을 수행하십시오.
#!/bin/sh
awk 'FNR == 1 { split($0, port, ","); FS=","; next }
{ for (i=2; i<=NF; ++i) if ($i == "open") print $1, port[i] }' file.csv |
while read -r ip port; do
telnet "$ip" "$port" # or whatever your command is
done
명령의 출력은 값을 읽고 명령을 호출하는 루프 awk
로 파이프됩니다 ( 입력 파일 이름 뒤에 파이프가 있음).while
|
IP 주소에 여러 포트가 열려 있는 경우 이 명령은 해당 주소에 대해 여러 번 실행됩니다.
답변2
사용 첫 번째 및 다음 해당 필드를 선택합니다 awk
.
awk -d "," -F '{print $1, $n...}