ls *.txt | wc -l
많은 파일이 포함 된 디렉토리를 시도 할 때 다음 오류가 발생 합니다.
-bash: /bin/ls: Argument list too long
이 “인수 목록”의 임계 값은 배포 또는 컴퓨터 사양에 따라 달라 집니까? 일반적으로 큰 결과의 결과를 다른 명령 ( wc -l
예 :)으로 파이프 하므로 터미널의 한계에 관심이 없습니다.
답변
귀하의 오류 메시지 인수 목록이 너무 오래 로부터 오는 * 의 ls *.txt
.
이 제한은 바이너리 프로그램과 커널 모두에 안전합니다. 당신은에서 볼 수있는 페이지 가 사용 계산 어떻게 그것에 대한 자세한 내용은합니다.
파이프 크기에는 이러한 제한이 없습니다. 따라서이 명령을 간단히 실행할 수 있습니다.
find -type f -name '*.txt' | wc -l
주의 : 현대 리눅스에서 (줄 바꿈 등) 파일 이름에 이상한 문자가 같은 도구로 이스케이프됩니다 ls
또는 find
,하지만 여전히에서 표시 * . 오래된 유닉스에 있다면이 명령이 필요합니다
find -type f -name '*.txt' -exec echo \; | wc -l
NB2 : 이름에 줄 바꿈이있는 파일을 만드는 방법이 궁금합니다. 트릭을 알고 나면 그렇게 어렵지 않습니다.
touch "hello
world"
답변
주로 Linux 커널 버전에 따라 다릅니다.
다음을 실행하여 시스템의 한계를 볼 수 있어야합니다
getconf ARG_MAX
이것은 쉘에 의해 확장 된 후 명령 행이 가질 수있는 최대 바이트 수를 알려줍니다.
Linux <2.6.23에서 한계는 일반적으로 128KB입니다.
Linux> = 2.6.25에서 제한은 128KB 또는 스택 크기의 1/4 (참조 ulimit -s
) 중 더 큰 값입니다.
자세한 내용은 execve (2) 매뉴얼 페이지 를 참조 하십시오.
불행히도, 배관 ls *.txt
이 문제를 해결하지 못할 것입니다. 한계는 쉘이 아닌 운영 체제에 있기 때문입니다.
셸이을 확장 한 *.txt
다음
exec("ls", "a.txt", "b.txt", ...)
일치 *.txt
하는 파일이 너무 많아 128KB 제한을 초과합니다.
당신은 뭔가를해야합니다
find . -maxdepth 1 -name "*.txt" | wc -l
대신에.
(그리고 개행을 포함하는 파일 이름에 대한 아래의 Shawn J. Goff의 의견을 참조하십시오.)
답변
다른 해결 방법 :
ls | grep -c '\.txt$'
생성 (또는 생성 시도) ls
보다 더 많은 출력을 생성 하더라도 ls *.txt
“인수가 너무 오래”문제가 발생하지 않습니다 . 인수를 전달 하지 않기 때문 ls
입니다. 참고 grep
파일 일치 패턴보다는 정규 표현식을합니다.
다음을 사용할 수 있습니다.
ls -U | grep -c '\.txt$'
(버전 ls
이이 옵션 을 지원 한다고 가정 ). 이렇게 ls
하면 출력을 정렬하지 않아도되므로 시간과 메모리를 모두 절약 할 수 있습니다.이 경우 파일을 계산하기 때문에 순서가 중요하지 않습니다. 출력 정렬에 소비 된 리소스는 일반적으로 중요하지 않지만이 경우 이미 많은 *.txt
파일 이 있다는 것을 알고 있습니다 .
그리고 단일 디렉토리에 너무 많은 파일이 없도록 파일을 재구성하는 것을 고려해야합니다. 이것은 가능할 수도 있고 아닐 수도 있습니다.
답변
MAX_ARG_PAGES는 커널 매개 변수 인 것으로 보입니다. find
and를 사용하면 xargs
이 한도를 해결하기위한 일반적인 조합이지만 작동하지 않을 것입니다 wc
.
find . -name \*\.txt
파일 의 출력을 파이핑하고 해당 파일의 행을 계산하면 해결 방법으로 사용됩니다.
답변
이것은 더러울 수 있지만 내 요구와 역량 내에서 작동합니다. 나는 그것이 매우 빨리 수행한다고 생각하지 않지만 그것은 내 하루를 시작할 수있게했습니다.
ls | grep jpg | <something>
90,000 개의 긴 jpg 목록을 가져 와서 avconv로 파이핑하여 timelapse를 생성했습니다.
이전에 ls * .jpg를 사용했습니다. | 이 문제가 발생하기 전에 avconv.