내 외장 하드 드라이브에는 1,242,276개의 일반 텍스트 파일이 포함된 디렉터리가 있습니다. 완전히 정리되지 않았고 파일 이름도 의미 없는 숫자입니다. 그 이유는 얼마 전 실수로 파티션을 지운 후 일부 복구 소프트웨어에 의해 파티션이 복구되었기 때문입니다.
나는 이제 해당 디렉토리에 있으며 "다면체"라는 단어에 대한 모든 파일의 내용을 검색하려고 합니다. 시도했지만 grep
실패했습니다.
$ grep polyhedron ./*
bash: /bin/grep: Argument list too long
이 디렉토리에 파일이 너무 많아서 그런가요? 이 밖에도 검색하고 싶은 키워드가 많이 있습니다. 지금 무엇을 할 수 있는지 알고 싶습니다.
답변1
find . -type f -print0 | xargs -0 grep polyhedron
용어가 일치하는 파일을 비슷한 이름의 폴더에 복사하는 등의 작업을 수행하고 싶을 수도 있습니다.
find . -type f -print0 | xargs -0 grep -l polyhedron | while read i; do cp "$i" ../polyhedron; done
일치하는 용어 사이에 겹치는 부분이 없다는 것을 알고 있는 경우(즉, 단일 파일에 "다면체"와 구성하려는 다른 용어가 없음) mv
복사하는 대신 이동할 수 있습니다 cp
.
답변2
파일이 너무 많아서가 아니라, 명령어의 매개변수 목록이 grep
너무 길기 때문이다. 이는 execve(2)
시스템 호출이 호출을 통해 전달되는 인수 목록과 환경 변수 목록의 결합된 크기에 적용하는 제한 입니다 .
ulimit -s
Linux에서는 2.6.23부터 다음을 사용하여 늘리거나 해제할 수 있는 관리 제한입니다(프로세스 스택 크기에 대한 제한도 설정함). 그래서
ulimit -s unlimited
당신에게 적합할 수도 있습니다.
그렇지 않으면 해결 방법(대부분 다른 답변에서 언급됨)에는 해당 제한에 맞게 인수 목록을 분할하거나 파일 목록을 execve
.
ls | xargs grep polyhedron
(알겠습니다. 파일 이름에는 숫자만 포함되어 있기 때문입니다.)
(xargs는 목록을 분할하고 제한에 도달하지 않도록 grep
필요한 만큼 많은 명령을 실행합니다 .)execve
find . -exec grep polyhedron {} +
동일하지만 이번에는 find
분할되었습니다.
grep -r polyhedron .
(grep이 지원하는 경우 -r
) 이번에는 3개의 매개변수 중 몇 문자만 전달되어 내부적으로 파일 목록을 grep
작성 grep
하고 execve 시스템 호출에 전달하지 않습니다.
일부 껍질에는내장그것을 지원하십시오.
내장 쉘의 경우에는 grep
이 문제가 발생하지 않습니다. 내장 쉘이 그렇지 않기 때문입니다.처형된시스템 호출을 통해 execve
.
ksh93을 사용하면 다음을 사용할 수 있습니다.
command -x grep polyhedron *
그리고 ksh93
분할됩니다.
zsh
다음 명령이 있습니다 zargs
.
zargs * -- grep polyhedron
여러 단어를 검색하려면 다음을 수행하세요.
grep -e word1 -e word2 ...
또는
grep 'word1
word2
...' ...
또는 단어 목록을 한 줄에 하나씩 파일에 넣고 사용하십시오.
grep -f that-file ...
답변3
이 디렉토리에 파일이 너무 많아서 그런가요?
예. 와일드카드 확장을 사용합니다. 이것이 명령줄에 확장된 모든 파일 이름입니다. 길이 제한으로 인해 이 작업이 실패했습니다. 이 한도를 확인하려면 다음을 시도해 보세요.
getconf ARG_MAX
이 밖에도 검색하고 싶은 키워드가 많이 있습니다. 지금 무엇을 할 수 있는지 알고 싶습니다.
grep 재귀 모드를 사용해 보셨나요?
grep -r polyhedron .
다른 답변에서 알 수 있듯이 다른 방법이 있습니다.이 기사문제에 대한 몇 가지 배경 지식과 이 길이 제한을 우회하는 방법에 대한 추가 예도 제공됩니다.
아이디어를 제공하기 위해 여기에 몇 가지 예를 복사했습니다.
사용 find
:
find /nas/data/accounting/ -type f -exec ls -l {} \;
사용 xargs
:
echo /nas/data/accounting/* | xargs ls -l
while 루프를 사용하세요:
find /nas/data/accounting/ -type f |
while read file
do
mv /nas/data/accounting/$file /local/disk/
done
답변4
당신은 시도 할 수 있습니다:
find . -print0|xargs -0 grep 'term1\|term2'
xargs
grep
기본 최대 매개변수를 사용하여 여러 명령이 생성됩니다. 여전히 "인수 목록이 너무 깁니다" 오류 가 발생 grep
하는 --max-args
경우 xargs
. 여러 용어로 검색할 수 있습니다 . 많은 문서가 있으므로 방법을 살펴보고 싶을 수도 있습니다.-print0
-0
\|
최적화grep
.