Maildir 디렉토리의 Bash 스크립트

Maildir 디렉토리의 Bash 스크립트

Maildir 디렉토리에 500개의 파일을 grep하고 싶습니다. 나는 명령을 내린다.

grep MyPattern *

오류 메시지가 나타납니다.

bash: /usr/bin/grep: Argument list too long

그래서 파일 목록을 MyFiles 파일에 저장하고 다음 명령을 실행합니다.

for i in $(`cat MyFiles`); do echo $i; done

grep을 실행하기 전에 에코를 수행하여 확인하고 싶습니다. 하지만 이로 인해 다음과 같은 오류가 발생합니다.

bash: 1434361691.M617282P6399V0000000000000808I00000000000E16C1_23.ananda-linux,S=10055:2,S: command not found

여기서 1434...는 디렉터리의 첫 번째 파일입니다.

그럼 원래 질문으로 돌아가겠습니다. 사서함에서 이러한 모든 파일을 찾기 위해 grep하는 방법. 50,000개 이상의 이메일이 들어 있는 더 큰 사서함을 가지고 있습니다.

답변1

grep현재 디렉터리에서 반복적으로 파일 목록을 구성해 보세요 .

grep -r MyPattern .

이는 하위 디렉토리에서 검색하므로 완전히 동일하지는 않지만 *메일 디렉토리의 경우 일반적으로 원하는 것입니다.

답변2

쉘이 외부 명령을 실행할 때 명령줄은 파일 이름 와일드카드 패턴(예:)을 확장한 후 *특정 길이를 초과해서는 안 됩니다 .

귀하의 경우 grep 'PATTERN' *확장은 쉘이 실행하기에는 너무 긴 명령입니다.

두 번째 예에서는:

for i in $(`cat MyFiles`); do echo $i; done

에 저장된 파일 이름을 반복하려고 시도했지만 MyFiles구문이 매우 잘못되었습니다.

$(`cat MyFiles`)

동일합니까?

$( $(cat MyFiles) )

이는 내용이 MyFiles명령으로 해석된다는 의미입니다. 이것이 바로 command not found오류가 발생하는 이유입니다.

이 문제를 해결하는 방법은 다양하지만 파일 내용을 반복하는 것은 좋은 접근 방식이 아닙니다.

Stephen은 훌륭한 솔루션을 제공했습니다.그의 대답에, 다른 하나는 현재 작업 디렉터리가 Maildir 폴더라고 가정하는 것입니다.

find . -type f -exec grep 'PATTERN' {} +

이 작업은 grep대규모 파일 배치에 대해 여러 번 수행됩니다.가능한 한 많이.

이는 다음과 유사합니다.

printf '%s\n' * | xargs grep 'PATTERN'

그러나 이 find명령은 공백과 줄 바꿈이 포함된 파일 이름을 처리합니다.

여기의 명령은 printf한 줄에 하나의 파일 이름을 출력합니다. grep 'PATTERN' *대부분의 경우 와 동일한 문제가 발생하지 않습니다 .내장명령이므로 쉘에서 외부 명령으로 실행할 필요가 없습니다.

cat루프 솔루션도 작동하지만 루프 출력 대신 간단히 다음을 수행할 수 있습니다.

for name in *; do
    grep 'PATTERN' "$name"
done

이는 다음과 같이 가정합니다.일반 파일만현재 디렉토리에 있습니다.

메일 메시지만 처리하려면 다음을 사용할 수 있습니다.

for name in *,*; do
    grep 'PATTERN' "$name" /dev/null
done

이는 하나 이상의 쉼표가 포함된 이름을 반복합니다. 또한 주어진 패턴과 일치하는 파일 이름을 /dev/null강제로 출력하도록 추가했습니다 . grep지원하는 경우 /dev/null대신 를 제거하고 사용할 수 있습니다 -H.grepgrep

이러한 루프는 grep디렉터리의 각 파일에 대해 한 번씩 수행되기 때문에 느립니다.

관련 정보