/bin/cat: 매개변수 목록이 너무 깁니다.

/bin/cat: 매개변수 목록이 너무 깁니다.

내 폴더에는 119766개의 파일이 있습니다. CSV 파일입니다. 모든 파일의 총 줄 수를 찾고 싶습니다.

다음 명령을 실행하려고 합니다.

cat * |wc -l

하지만 다음과 같은 오류가 발생합니다.

-bash: /bin/cat: 매개변수 목록이 너무 깁니다.

어떻게 해야 하나요? 이 문제를 해결할 방법이 있나요?

한 가지 추가하고 싶은 점은 전체 행 수가 매우 커진다는 것입니다.

답변1

글쎄, 이 질문에 새로운 근거를 제공하려면 cat다음과 같이 해야 합니다.

find . -type f -exec cat {} + | wc -l

허용되는 최대 파일 이름 수를 사용하여 a()를 계속해서 cat수행하고 모든 것을 .+wc-maxdepth 1

대안으로 --files0-fromGNU 옵션을 사용할 수 있습니다.wc

find . -type f -print0 | wc -l --files0-from=- | tail -1

이 옵션을 사용하면 wc내용을 읽는 것이 아니라파일 이름표준 입력에서 널 문자로 구분됩니다. 를 사용하면 -print0이러한 find파일 이름이 널 바이트로 구분되어 인쇄됩니다. 각 파일의 줄 수는 계속 인쇄 되므로 wc끝 부분의 요약 줄을 제외한 모든 줄을 건너뛰는 것이 좋습니다 tail.

두 솔루션 모두 모든 로케일에서 작동한다는 장점이 있는 반면, @cas의 솔루션은 조정되어야 합니다(예: "total"은 독일어로 "insgesamt"입니다).

답변2

각 개별 파일의 줄 수를 원하는 경우:

find . -type f -exec wc -l {} + | awk '! /^[ 0-9]+[[:space:]]+total$/'

그 중 일부는 너무 많은 파일을 처리하고 있기 때문에 총 줄 수를 제외했습니다. 단일 명령줄에 가능한 한 많은 파일 이름을 넣으려고 시도 find ... -exec ... +하지만 이는 119,766개 파일보다 훨씬 적습니다.... 호출당 최대 수천 개에 불과하며 wc각 파일은 해당 파일을 생성합니다. 자체 결과 별도의 "마스터" 라인.

모든 파일의 총 줄 수를 병합하려면 다음 방법 중 하나를 사용하세요.

find . -type f -exec wc -l {} + | 
    awk '/^[ 0-9]+[[:space:]]+total$/ {print $1}' | 
    xargs | sed -e 's/ /+/g' | bc

이것은 단지 총 줄 수에 대한 줄 수를 인쇄하고, 파이프를 사용하여 xargs줄의 모든 개수를 얻은 다음, sed를 사용하여 공백을 +부호로 변환한 다음, 많은 양의 데이터를 파이프하여 bc계산을 수행합니다.

출력 예:

$ cd /usr/share/doc
$ find . -type f -exec wc -l {} + | 
    awk '/^[ 0-9]+[[:space:]]+total$/ {print $1}' | 
    xargs | sed -e 's/ /+/g' | bc 
53358931

업데이트 2022-05-05

wc -l실행하는 것이 가장 좋습니다 sh. 이렇게 하면 파일 이름을 호출할 때 문제가 발생할 위험이 방지됩니다 . total총 줄이 출력의 마지막 줄인 것 외에는 wc"total"이라는 파일의 출력과 실제 총 줄을 구별할 수 있는 방법이 없습니다. 따라서 " total" ” 간단한 awk 스크립트가 안정적으로 작동하지 않습니다.

개별 파일의 개수를 표시하려면(전체 제외):

find . -type f -exec sh -c 'wc -l "$@" | sed "\$d"' sh {} +

이는 wc -l모든 파일 이름에 대해 실행되며 각 일괄 실행에서 마지막 행("전체" 행)을 제거합니다 -exec.

sed 스크립트에서는 $d스크립트가 더 일반적인 작은따옴표 문자열이 아닌 큰따옴표 문자열에 있기 때문에 이스케이프해야 합니다. 전체 sh -c문자열이 작은따옴표이므로 큰따옴표가 사용됩니다. 작은따옴표 안에 작은따옴표를 삽입하는 $것보다 기호 를 이스케이프 처리하는 것이 더 쉽고 읽기 쉽습니다.'\''

합계만 표시:

find . -type f -exec sh -c 'wc -l "$@" | awk "END {print \$1}"' sh {} + |
  xargs | sed -e 's/ /+/g' | bc

sedby를 통해 전달된 각 파일 배치의 마지막 줄을 삭제하는 대신 각 배치의 마지막 줄("전체")만 인쇄합니다. 그런 다음 의 출력은 각 숫자 사이에 문자가 포함된 단일 라인(xargs)으로 변환된 다음(sed는 공백을 +로 변환함) 계산을 수행하기 위해 파이프됩니다.wcshfind ... -execawkfind+bc

$dsed 스크립트의 스크립트와 마찬가지로 $1awk 스크립트의 스크립트도 큰따옴표로 인해 이스케이프되어야 합니다.

답변3

파일이 너무 많으면 정보를 표준 출력으로 보내고 싶지 않을 수 있으므로 다음을 수행할 수 있습니다.

IFS="\n"; for file in find ./ -type f; do wc -l "$file" >> ~/linecount.txt; done

관련 정보