문자열이 포함된 파일을 하나의 문서로 결합

문자열이 포함된 파일을 하나의 문서로 결합

이 스크립트를 기반으로 합니다.

find . -name "*.txt" | grep 'LINUX/UNIX'

그리고

find . -name "*.txt" | grep 'LINUX/UNIX' | xargs cp <to a path>

~에서여기 , 특정 문자열을 찾는 파일을 grep한 다음 해당 문자열이 포함되어 있으면 디렉터리에 복사한 다음 별도의 파일로 보관할 수 있습니다. 이러한 파일을 일관된 문서로 어떻게 구성합니까?

내 아이디어의 예는 다음과 같습니다. 수백 개의 폴더에 별도의 파일로 배포된 인용 아카이브가 있으며, 폴더 이름은 해당 주제입니다. 따라서 "philosophy/ontology/concepts/aletheia/notes.tex"에는 aletheia와 같은 철학적 개념에 대한 모든 메모가 포함됩니다.

모두 일부 명명 규칙(이름은 항상 Notes.tex)을 따르므로 grep이 쉽습니다. 나는 그것들을 찾을 수 있지만, 그것들을 찾을 뿐만 아니라 해당 문자열을 포함하는 모든 파일을 하나의 큰 파일로 연결하는 스크립트를 갖고 싶습니다.

답변1

*.txt현재 디렉터리나 특정 디렉터리가 포함된 다음 디렉터리에서 이름이 일치하는 일반 파일을 선택합니다 .(특정 정규식과 일치하는 항목이 없음) 이러한 파일을 찾은 순서대로 연결하려면 다음을 사용할 수 있습니다.

find . -name '*.txt' -type f -exec grep -q -F 'LINUX/UNIX' {} \; -exec cat {} + >myfile

또는

find . -name '*.txt' -type f -exec sh -c '
    for pathname do
        grep -q -F "LINUX/UNIX" "$pathname" && cat "$pathname"
    done' sh {} + >myfile

grep여기서는 유틸리티와 해당 -q옵션이 사용됩니다. 이로 인해 아무것도 출력되지 않지만 주어진 패턴이 일치하면 "성공"을 나타내는 0 종료 상태로 종료됩니다. 문자열을 포함하는 파일만 선택하기 위한 테스트로 위의 두 명령에서 이 종료 상태를 사용합니다 LINUX/UNIX.

패턴을 다음과 같이 해석하게 -F만듭니다 .grep정규 표현식이 아닌 이렇게 하면 명령이 조금 더 빨라질 수 있지만 문자를 특별하게 처리 *this*하지 않고 문자열을 검색하는 것에 대해 걱정할 필요가 없다는 의미이기도 합니다 *(정규식에서는 특별하기 때문입니다).

두 명령 모두 연결된 파일 데이터를 이름이 지정된 파일에 기록합니다 myfile. 파일이 이미 있으면 잘리고(비어지고) 그렇지 않으면 생성됩니다. 의도적으로 출력 파일 이름을 선택했습니다.아니요find명령 , 즉 로 끝나지 않는 명령을 통해 찾을 수 있습니다 .txt.


현재 질문에는 findwith 의 출력을 필터링 grep한 다음 cpvia 를 호출하는 코드가 포함되어 있습니다 xargs. 이는 사용자 자신의 코드에는 문제가 없으며 몇 가지 문제가 있습니다. 한 가지 문제는 파일의 내용을 연결하지 않는다는 것이고, 또 다른 문제는 파일의 내용이 아닌 grep출력의 경로 이름 에 적용된다는 것입니다 . find당신은 또한 볼 수 있습니다찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?이것은 관련이 있습니다.

문제의 코드 형식을 사용하여 실제로 문제를 해결하세요.이것문제는 find경로 이름 목록을 생성한 다음 grep관심 있는 경로 이름을 선택하고 마지막으로 다음을 수행하는 것입니다 cat.

find . -name '*.txt' -type f -print0 |
xargs -0 grep -lZ -F 'LINUX/UNIX' |
xargs -0 cat >myfile

.txtfind이는 이름이 from으로 끝나는 파일에 대한 첫 번째 경로 이름 목록을 xargsnull로 구분된 목록으로 전달합니다. 유틸리티 는 이를 xargs호출 하고 일치 항목이 포함된 파일의 경로 이름을 다시 빈으로 구분된 목록으로 출력합니다. 이로 인해 일치하는 파일의 경로 이름이 출력되어 개행으로 구분된 목록 대신 빈으로 구분된 목록으로 변환됩니다.grepgrep-l-Z

그런 다음 각 파일에 대해 xargs호출되는 최종 함수가 이 목록을 읽습니다 . 이전과 같이 cat연결 결과를 작성합니다 .myfile

이는 문제를 해결하는 더 어색한 방법입니다. 파이프라인 단계 사이의 파일 목록 형식을 잊어버릴 수 있으며 코드를 실행하는 사람이 GNU 시스템 또는 최소한 GNU 도구(예: 휴대용이 아닙니다).

관련 정보