로그 파일이 있고 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
여기.
cut
1+ 와 함께 예제를 사용하면 다음과 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
동일한 아이디어를 사용하여 awk
7번째 필드( ) substr($F[6],1)
의 하위 문자열을 인쇄하고 .","
출력에 쉼표( )를 추가합니다. Perl은 0부터 계산을 시작하고 awk는 1부터 계산을 시작하므로 awk에서 as를 사용하여 in을 사용하여 7번째 필드를 $F[6]
가져옵니다 . 지침을 찾을 수 있습니다perl
$7
perl
여기.
답변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