bash를 사용하여 csv 파일을 구문 분석하는 방법

bash를 사용하여 csv 파일을 구문 분석하는 방법

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 인 필드를 찾으면 openIP 주소(첫 번째 필드)와 해당 포트 번호를 인쇄합니다.

질문의 데이터를 고려하면 이 명령의 출력은 다음과 같습니다.

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

관련 정보