node_modules
저는 node.js 폴더의 내용이나 Python의 virtualenv
기본 종속성을 검사하는 빠른 도구를 작성 중입니다. 이에 대한 빠른 첫 번째 근사치로 다음 명령을 작성했습니다.
find . | xargs file | awk '/C source/ {print $1} /ELF/ {print $1}'
거짓 긍정은 허용하지만 거짓 부정은 허용하지 않습니다(예: 파일에 문자 그대로 문자열이 포함되어 있거나 ELF
의심 스러운 것으로 표시될 수 있음). 그러나 이 스크립트는 긴 파일 이름( 분할되므로)과 공백이 포함된 파일 C source
에서도 실패할 수 있습니다 . xargs
공백으로 분할됨) 및 줄바꿈이 포함된 파일 이름(find가 경로를 구분하기 위해 줄바꿈을 사용하기 때문).
find
출력 file {}
(아마도 출력에서 경로를 완전히 제거하기 위해 몇 가지 추가 옵션을 사용 file
)이 특정 정규식과 일치하는지 확인하여 생성된 경로를 필터링하는 방법이 있습니까?
답변1
깨달음을 달성하는 핵심 요소는 find
다음과 같습니다.
find
업무는 파일을 찾는 것이 아니라 표현식을 평가하는 것입니다. 예,find
물론 파일을 찾을 수 있지만 실제로는 부작용일 뿐입니다.
이 문제에 대해 알아둘 만한 또 다른 접근 방식이 있습니다(Unix Power Tools에도 설명되어 있음)."-exec를 사용하여 사용자 정의 테스트 만들기"):
find . -type f -exec sh -c 'file -b "$1" | grep -iqE "^ELF|^C source"' sh {} \; -print
이 필터링 방법은 파일 이름을 인쇄하는 것 이상의 용도로 사용할 수 있으므로 알아두는 것이 좋습니다. -print
연산자를 원하는 다른 연산자(다른 -exec
연산자 포함)로 변경하고 원하는 대로 수행하면 됩니다.
거기예이 명령의 성능 결함(다음에도 나타남)또 다른 대답\;
), 우리는 사용하고 있지 않기 때문에 +
각 파일에 대해 쉘을 생성합니다. 한 번에 여러 파일을 명령 +
에 전달 하고 루프를 사용하여 처리 하면 성능이 크게 향상됩니다 .sh
for
find . -exec sh -c 'for f do file -b "$f" | grep -qE "^ELF|^C source" && printf %s\\n "$f"; done' sh {} +
다음 두 명령을 실행하고 출력을 비교하여 직접 비교 내용을 확인할 수 있습니다 time
.
time find . -exec sh -c 'for f do file -b "$f" | grep -qE "^ELF|^C source" && printf %s\\n "$f"; done' sh {} +
time find . -exec sh -c 'file -b "$1" | grep -qE "^ELF|^C source" && printf %s\\n "$1"' sh {} \;
그러나 실제 요점은 다음과 같습니다.
for
에서 출력되는 파일 목록에 대해 쉘 루프를 실행하지 마십시오 find
.find
대신 연산자를 사용하여 각 파일에서 수행해야 하는 작업을 직접 실행할 수 있습니다 -exec
.포함시키다쉘 for
루프이내에명령 하나만 find
하면 됩니다.
몇 가지 추가 이유:
답변2
가장 간단한 방법은 각 파일에 대해 작은 스크립트를 실행하고 짧은 패턴 출력을 확인 file
하고 출력이 file
일치 ELF
하거나 C source
경로를 인쇄하면 경로가 에 전달되는 것입니다 $0
.
find . -type f -exec sh -c \
'file -b "$0" | grep -q "^ELF\|^C source" && printf %s\\n "$0"' {} \;
이 계획은 원래 계획에 비해 다음과 같은 장점이 있습니다.
-type f
출력에 의존하는 대신 즉시 디렉터리를 필터링합니다.file
매개변수를 전달하면 {}
파일 이름의 공백이나 개행과 관련된 문제를 피할 수 있습니다.