쉘 - 로그에서 날짜와 시간 추출

쉘 - 로그에서 날짜와 시간 추출

내 웹 서버 로그 파일은 다음과 같습니다.

2001:67c:1220:80c:d4:985a:df2c:d717 - - [22/Feb/2019:07:49:01 +0100] "GET / HTTP/1.1" 200 58266 "-" "curl/7.61.1"
2001:67c:1220:80c:d4:985a:df2c:d717 - - [22/Feb/2019:08:49:01 +0100] "GET / HTTP/1.1" 200 58341 "-" "curl/7.61.1"
2001:67c:1220:808::93e5:8ad - - [22/Feb/2019:08:56:10 +0100] "POST /wp-cron.php?doing_wp_cron=1550822170.2184400558471679687500 HTTP/1.1" 200 3279 "https://ios-example.com/wp-cron.php?doing_wp_cron=1550822170.2184400558471679687500" "WordPress/4.9.9; https://ios-example.com"
...

이 형식으로 날짜와 시간을 추출해야 합니다 22/Feb/2019:07:49:01.

이것이 내가 지금 가지고 있는 것입니다(이 스레드에서 뻔뻔하게 복사했습니다:행에서 날짜 필드 추출):

file="filename"
while IFS= read -r line
do
    echo "`cut -d '[' -f2 $line | cut -d ' ' -f1`" # echoing now for testing purposes
done <"$file"

스크립트를 실행할 때의 출력은 다음과 같습니다.

cut: '2001:67c:1220:80c:d4:985a:df2c:d717': Adresář nebo soubor neexistuje
cut: '[22/Feb/2019:07:49:01': Adresář nebo soubor neexistuje
cut: +0100]: Adresář nebo soubor neexistuje
cut: '"GET': Adresář nebo soubor neexistuje
cut: /: je adresářem
cut: 'HTTP/1.1"': Adresář nebo soubor neexistuje
cut: 200: Adresář nebo soubor neexistuje
cut: 58266: Adresář nebo soubor neexistuje
cut: '"-"': Adresář nebo soubor neexistuje
cut: '"curl/7.61.1"': Adresář nebo soubor neexistuje
22/Feb/2019:08:49:01
22/Feb/2019:08:56:10
22/Feb/2019:08:56:10
22/Feb/2019:09:24:33
22/Feb/2019:09:24:33
22/Feb/2019:09:43:13
22/Feb/2019:09:43:24
...

"Adresář nebo soubor neexistuje"는 "디렉토리나 파일이 존재하지 않습니다"를 의미합니다.

나에게 알려지지 않은 이유로 인해 로그 파일의 첫 번째 줄에서는 작동하지 않지만 파일의 나머지 부분에서는 작동합니다.

답변1

여러 가지 실수를 저질렀습니다.

  • cut은 파일 이름을 인수로 사용합니다.
  • 큰따옴표를 잊어버렸습니다(")

따라서 최소한의 변경으로 예제를 다시 작성하면 다음과 같습니다.

  • 어떤 것의 목적을 가리킨다.$(바꾸다`. 이는 더욱 강력하며 재귀적으로 작동합니다.
  • 어떤 것의 목적을 가리킨다.${VARIABLE_NAME}$VARIABLE_NAME 대신. 이게 더 튼튼해요

새로운 버전

file="filename"
while IFS= read -r line
do
    EXTRACT_DATE=$( echo "$line" | cut -d '[' -f2 | cut -d ' ' -f1  )
    echo "${EXTRACT_DATE}"        
done <"$file"

답변2

오류를 일으키는 주요 문제는 읽기 행을 에서 읽을 $line파일 이름 으로 사용하고 있다는 것입니다.cut

echo이를 사용하여 명령 대체 결과를 출력 할 수도 있습니다 . 이것은 안티 패턴입니다. 파이프라인을 실행하기만 하면 됩니다. 명령을 바꿀 필요가 없습니다 echo. 결과를 자체적으로 터미널에 출력합니다.

여기서는 다음을 사용하여 파일에서 읽은 행을 printf제공합니다 .cut

file="filename"

while IFS= read -r line; do
    printf '%s\n' "$line" | cut -d '[' -f2 | cut -d ' ' -f1
done <"$file"

다음으로 주목해야 할 점은 while루프가 완전히 불필요하다는 것입니다. cut두 번 전화를 걸었 습니다.각 라인로그 파일에 있습니다. 이 cut유틸리티는 자체적으로 파일을 한 줄씩 읽을 수 있습니다.

file="filename"

cut -d '[' -f2 "$file" | cut -d ' ' -f1

또는 GNU를 사용할 수도 있습니다 grep.

grep -oP '(?<=\[)[^ ]+' "$file"

(이렇게 하면 첫 번째 공백 이후부터 첫 번째 공백 이전의 모든 내용이 추출됩니다 [.)

또는 표준 sed,

sed 's/\].*//; s/.*\[//; s/ .*//' "$file"

(이렇게 하면 첫 번째 이후의 모든 항목이 제거되고 ]첫 번째 이후의 모든 항목이 제거 [된 다음 공백과 나머지가 제거됩니다.)

관련된:

관련 정보