스크립트에서 grep의 출력을 안전하게 사용하는 방법은 무엇입니까?

스크립트에서 grep의 출력을 안전하게 사용하는 방법은 무엇입니까?

스크립트에서 일부 텍스트가 포함된 파일을 찾고 싶습니다. 텍스트가 있는 파일과 텍스트가 있는 파일 내의 전체 줄을 알아야 합니다. grep이 작업을 수행하는 유틸리티이지만 다음과 같은 경우 출력을 사용 가능한 형식으로 어떻게 얻을 수 있습니까? :파일 이름에? 명령 처럼 자주 사용할 수 있는 --porcelain모드 가 있나요 ?grepgit

test-num:1:date:jan-2예: grep하고 싶은 이름의 파일로 가득 찬 폴더가 있습니다 . 파일에는 FAILURE:<some reason>또는 SUCCESS:<some reason>(다른 내용 중에서)이 포함되어 있습니다. 특정 이유를 검색하고 나중에 처리할 수 있도록 파일 이름과 이유(텍스트 전체 줄이면 좋음)를 저장하는 스크립트가 필요합니다. 출력은 코드를 실행할 수 있는 한 모든 종류의 데이터 구조일 수 있습니다.

답변1

와 같은 것은 없으며 grep --porcelain파일 이름의 특수 문자를 처리하는 것은 UNIX에서 항상 나중에 고려되었습니다. 효율성을 희생하면서 다음과 같은 것을 시도해 볼 수 있습니다.

pattern='some pattern'
for file in ./*; do
    grep -- "$pattern" "$file" | while read -r line; do
        printf 'file: %s, line: %s\n' "$file" "$line"
    done
done

답변2

GNU grep의 최신 버전에는 -Z출력을 명확하게 만드는 옵션이 있지만 대부분 grep -lZ … | xargs -0. 줄 내용을 나열하는 경우에도 여전히 작동합니다. null 바이트는 콜론을 대체하고 줄 내용은 여전히 ​​개행으로 끝나지만 1. 쉘은 null 바이트를 잘 처리하지 못하므로 이 출력을 구문 분석하는 데 어려움을 겪게 됩니다. .

약간의 성능 저하가 있는 간단한 솔루션 중 하나는 각 파일에 대해 개별적으로 grep을 실행하는 것입니다.

또 다른 해결책은 Perl이나 Python과 같은 언어를 사용하는 것입니다. Perl은 grep을 에뮬레이트하는 데 꽤 능숙합니다.  grep REGEX기본적으로 입니다 perl -ne '/REGEXP/ and print'.

그러나 출력이 실제로 모호하지 않은 경우에는 이것이 전혀 필요하지 않을 수도 있습니다. 예를 들어, 일치하는 줄에 콜론이 포함되어 있지 않으면 파일 이름은 줄에서 마지막 콜론까지의 모든 항목입니다. 일치하는 줄이 모두 SUCCESS또는 로 시작 FAILURE하고 이러한 단어가 파일 이름에 나타나지 않으면 이를 사용하여 구분 등을 찾을 수 있습니다.

¹ 줄 바꿈으로 끝나는 레코드가 아닌 Null로 끝나는 레코드를 필터링하는 데 사용하는 경우를 제외하고 -znull은 파일 이름 종결자이자 결과 종결자입니다. 출력이 없으면 -o출력 레코드가 파일 이름이고 출력의 레코드가 일치하는 교대로 여전히 모호하지 않습니다.

답변3

grep의 출력을 안전하게 사용하는 방법대본에서?

... 출력은 어떤 종류로든 가능합니다.데이터 구조,코드를 실행할 수만 있다면 말이죠.

쉘 스크립트에는 실제로 데이터 구조가 없습니다. 배열이 있지만 그게 전부입니다. 파이프로 연결된 출력을 배열로 안전하게 가져오는 것은 쉽지 않습니다. (파일 이름~할 수 있다줄 바꿈을 포함합니다.)

가장 좋은 방법은코드 실행쉘 스크립트에서 파일을 덮어쓰는 것은 나중에 사용하기 위해 파일 이름을 저장하려고 하지 않고 파일 위에 코드를 실행하는 것입니다.

이렇게 하려면 다음을 사용하세요 find.

find somedir -type f -exec grep -q somepattern {} \; -exec somecommand {} \;

그러나 귀하의 질문을 더 자세히 읽어 보면 실제로는 원하지 않는 것 같습니다.코드 실행파일에 대해 특정 줄에서 일부 텍스트 처리를 수행하고 싶을 뿐입니다. 이 경우 GNU Grep 옵션이 -z아마도 당신이 원하는 것일 것입니다. 그것과 Sed 또는 Awk에 대한 지식이 귀하의 질문을 처리할 것입니다.


파일 명명 규칙을 변경하는 것이 현명할 수 있습니다.

관련 정보