잘라내기 명령을 결합하고 사용자 정의 구분 기호를 사용할 수 있나요?

잘라내기 명령을 결합하고 사용자 정의 구분 기호를 사용할 수 있나요?

로그 파일이 있고 404d가 있는 GET 요청에서 URL을 추출해야 합니다.

나는 다음을 사용했습니다 :

grep 404 testfile.txt | cut -f 2 -d '"' | cut -f 2 -d '/' | cut -f 1 -d ' ' | sort -u

이렇게 컷 명령을 함께 넣는 것은 권장하지 않습니다. 한 줄로 합칠 수 있나요? 예를 들어, 세 번째 "/"와 여섯 번째 ""부터 자르기를 시작합니다.

로그 파일 예:

ip - - [12/Dec/2019:13:18:00 +0000] "GET /test.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"

ip - - [12/Dec/2019:13:18:00 +0000] "GET /403dz2.html HTTP/1.1" 404 492 "-" "python-requests/2.18.4"

결과:

403dz2.html,
is0pmq.html,
iw30ce.html,
nbk0px.html,

답변1

이전처럼 명령을 함께 파이핑하는 데는 아무런 문제가 없습니다. cut그러나 큰 입력에 대해 이를 수행하는 더 효율적인 방법이 있을 수 있다는 점을 알아야 합니다. 이는 귀하의 예에서 입력 파일이 터미널에 출력되기 전에 명령으로 5번 처리되어야 하기 때문입니다( grep필터링을 위해 한 번, 별도의 cut구문 분석 명령 3개, 구문 분석을 위해 한 번 sort). 파이프를 적게 사용가능한성능이 향상되지만 이는 궁극적으로 명령 자체와 수행하는 작업에 따라 달라집니다(즉, 세 개의 빠르고 간단한 작업이 하나의 크고 계산 집약적인 작업보다 빠릅니다). 입력 데이터가 비교적 작은 경우에는 파이프라인 방법을 사용하든 다음 방법 중 하나를 사용하든 차이가 없습니다.

노트:다음 예제가 OP의 원래 명령 체인과 비교하여 얼마나 효율적이거나 빠른지 잘 모르겠습니다. 사용 사례에 따라 일부는 다른 것보다 "더 좋을" 수 있습니다.

사용 awk: (존중)

awk '$9=="404" {print substr($7,2)","}' testfile.txt

위의 내용은 Romeo의 답변과 유사하지만 로그 출력의 파일 이름에서 선행 슬래시를 제거하고 원하는 결과와 일치하도록 끝에 쉼표를 추가합니다. awk입력 데이터를 한 줄씩(기본적으로) 구문 분석하고 각 줄을 공백 구분 기호(기본적으로)로 분할하는 명령입니다. 이 명령은 9번째 필드(HTTP 응답 코드)를 확인 404하고 일치하는 경우 7번째 필드의 하위 문자열을 두 번째 문자부터 끝( )까지 가져와 substr($7,2)해당 필드 뒤에 쉼표( )를 추가한 후 출력을 인쇄합니다. ","다음에 대해 더 자세히 읽을 수 있습니다.awk 여기.

cut1+ 와 함께 예제를 사용하면 다음과 sed같습니다.

grep '" 404' testfile.txt | cut -d' ' -f7 | sed 's/\///; s/$/,/'

파일 이름을 추출하는 데 세 가지 별도의 잘라내기 명령이 필요하지 않으며 공백 구분 기호를 사용할 경우 하나만 필요합니다. 이 cut명령은 로프를 당깁니다 /403dz2.html. 그러면 sed앞의 슬래시( s/\///)가 제거되고 s/$/,/끝에 쉼표( )가 추가됩니다. 무엇 sed인가요실제로여기서 수행되는 작업은 대체입니다. 문자열은 s/replace this/with this/첫 번째 sed문자열( )이 두 번째 문자열 replace this( with this)로 대체됨을 나타냅니다. 첫 번째 바꾸기 명령은 아무것도 sed바꾸지 않도록 지시하고 /, 두 번째 명령은 $줄 끝( )을 로 "바꿉니다" ,. 다음에 대해 더 자세히 읽을 수 있습니다.sed 여기. 또한 내가 grep이 작업을 수행하고 있다는 점에 유의하십시오 " 404. 이는 약간 해키지만 grep다른 곳에 나타나는 줄(예: 파일 이름, 파일 크기, 날짜 등)에 대해서는 404를 반환 하지 않습니다.

사용 perl:

grep '" 404' testfile.txt | perl -lane 'print substr($F[6],1).","'

이는 예제와 유사 하지만 입력을 필터링 awk하는 데에도 사용됩니다 . grep동일한 아이디어를 사용하여 awk7번째 필드( ) substr($F[6],1)의 하위 문자열을 인쇄하고 .","출력에 쉼표( )를 추가합니다. Perl은 0부터 계산을 시작하고 awk는 1부터 계산을 시작하므로 awk에서 as를 사용하여 in을 사용하여 7번째 필드를 $F[6]가져옵니다 . 지침을 찾을 수 있습니다perl$7perl여기.

답변2

구분자 공백( )을 사용하여 필터링 해 보셨나요?

awk '$9=="404" {print $7}' testfile.txt|sort -u

또는 다음을 사용하세요.

grep 404 testfile.txt | cut -f 7 -d ' '|sort -u

PS 예를 들어 다운로드 길이가 404바이트인 경우 두 번째 방법이 일치합니다. 또는 연도에 404 문자열이 포함되어 있습니다. 또는 요청된 URL에 이 문자열이 포함되어 있습니다.

답변3

사용 awk명령:

awk -F '[ /]' '/ 404 / {print $10|"sort -u"}' testfile.txt

설명하다:

  • -F '[ /]': 공백 " "과 슬래시 "/"를 구분 기호로 사용합니다. (여러 구분 기호)
  • / 404 /: "404"를 포함하는 줄만 일치합니다. grep " 404 " testfile.txt작업과 같습니다 .

노트: "404" 전후에 약간의 공백이 있습니다.

이렇게 하면 응답 코드가 아닌 URL에 나타날 수 있는 잘못된 긍정 일치가 제거됩니다. 예를 들어, 다음 줄은 일치하지 않습니다.

ip - - [12/Dec/2019:13:18:00 +0000] "GET /test404.html HTTP/1.1" 200 710 "-" "python-requests/2.18.4"

노트:test404.htmlURL에 다음이 포함됨404하지만 응답 코드는200. 따라서 "404" 앞뒤에 공백이 있어야 합니다.

  • print $10: 10번째 필드를 표시하려면 공백과 슬래시를 구분 기호로 사용하세요.
  • | sort -u : 결과를 정렬하고 중복 인스턴스를 하나만 가져옵니다. (즉, 행만 표시)
  • testfile.txt: 일치시킬 줄이 포함된 파일입니다.

노트: 다른 행이 있지만 404관심이 없다고 가정하면 다음을 사용하여 일치를 좁힐 수 있습니다.

awk -F '[ /]' '/GET.* 404 / {print $10|"sort -u"}' testfile.txt

수정 내용:

  • /GET.* 404 /GET: " 다음에 다른 내용이 오고 그 다음에 "가 포함된 404행만 일치합니다 .

마침내:

  • URL 앞에 슬래시를 추가하려면 다음을 사용하세요.

    awk '/ 404 / {print $7|"sort -u"}' testfile.txt
    
  • URL 뒤에 쉼표를 추가하려면 다음을 사용하세요.

    awk -F '[ /]' '/ 404 / {print $10","|"sort -u"}' testfile.txt
    
  • URL 앞에 슬래시를 추가하고 URL 뒤에 쉼표를 추가하려면 다음을 사용하세요.

    awk '/ 404 / {print $7","|"sort -u"}' testfile.txt
    

관련 정보