로그 파일에서 경로 이름을 추출하는 방법은 무엇입니까?

로그 파일에서 경로 이름을 추출하는 방법은 무엇입니까?

이는 다음과 유사합니다.이것, 그러나 strace의 출력을 다음과 같은 파일에 저장했습니다.

...
3691  fcntl(2, F_GETFD)                 = 0
3691  access("/etc/suid-debug", F_OK)   = -1 ENOENT (No such file or directory)
3691  access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
3691  openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
3691  fstat(3, {st_mode=S_IFREG|0644, st_size=243756, ...}) = 0
3691  mmap(NULL, 243756, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff0696c2000
3691  close(3)                          = 0
3691  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcrypto.so.1.1", O_RDONLY|O_CLOEXEC) = 3
3691  read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\t\0\0\0\0\0"..., 832) = 832
3691  fstat(3, {st_mode=S_IFREG|0644, st_size=3076960, ...}) = 0
...

경로를 인쇄하는 쉬운 방법이 있습니까? 이 경우 awk를 사용하여 경로를 구문 분석하는 것이 쉽지 않은 것 같습니까?

답변1

grep과 sed를 함께 사용하는 것이 좋습니다.

 ... | grep '"/' | sed 's/^.*"\(/[^"]*\)".*$/\1/'

이는 슬래시로 시작하는 데이터 문자열에서 일부 오탐지를 생성할 수 있고 리터럴 큰따옴표가 포함된 경로 이름으로 인해 실패할 수도 있으며 한 줄에서 두 번째 경로를 찾지 못할 수도 있지만 여기 한 가지 시작이 있습니다. .

경로 매개변수를 사용하여 "openat" 및 기타 시스템 호출을 grep할 수도 있습니다.

 ... | grep -e openat -e access | sed ...

오탐지를 더욱 줄이기 위해.

답변2

세 번째 인수로 GNU awk를 사용하십시오 match().

$ awk 'match($0,/"(\/[^"]+)/,a){print a[1]}' file
/etc/suid-debug
/etc/ld.so.preload
/etc/ld.so.cache
/lib/x86_64-linux-gnu/libcrypto.so.1.1

그렇지 않으면 모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.

$ awk 'match($0,/"\/[^"]+/){print substr($0,RSTART+1,RLENGTH-1)}' file
/etc/suid-debug
/etc/ld.so.preload
/etc/ld.so.cache
/lib/x86_64-linux-gnu/libcrypto.so.1.1

답변3

다음을 수행할 수 있습니다.

grep -Po '(\(|, )"\K/[^"]*'

"또는 로 시작하는 문자가 /아닌 ("시퀀스를 찾습니다 , ".

이것으로도 충분할 수 있습니다:

grep -Po '"\K/[^"]*'

"로 시작하는 비문자 시퀀스의 경우 /뒤에 ".

절대 경로(로 시작하는 경로)만 보고합니다 /. 그들은 에서와 같이 경로의 일부가 아닌 것을 보고할 수 있으며, write("// some C++ comment", ...)이는 그런 것들에 의해 속일 수 있습니다 write("foo \"/bar\" baz"...).

상대 경로를 허용하는 보다 엄격한 일치를 위해서는 정규식에서 경로 매개 변수를 사용하는 모든 시스템 호출을 재정의해야 합니다. 샘플에서:

grep -Po '^\d+\s+((open|access)\(|openat\(\S+, )"\K(\\.|[^"])*'

(?!.*\) = -1)실패한 시스템 호출에서 경로를 제외하려면 정규식에 (부정 예측 어설션)을 추가할 수 있습니다 . -z// 옵션 및 파일 관련 시스템 호출만 추적을 참조하세요 --successful-only.-e status=successful strace-e trace=%file

관련 정보