디렉토리에 있는 파일의 최소 및 최대 줄 수를 가져옵니다.

디렉토리에 있는 파일의 최소 및 최대 줄 수를 가져옵니다.

내 디렉토리에는 약 500만 개의 텍스트 파일이 있습니다. 모두 동일한 형식입니다(특별한 것은 없으며 한 줄에 정수가 포함된 일반 텍스트 파일만 있음). 이 모든 파일의 최대 및 최소 줄 수를 계산하고 싶습니다.

먼저 다음과 같이 모든 행 번호를 작성해 보았습니다. (그리고 나서 이 목록에서 최소값과 최대값을 찾는 방법을 연습했습니다.)

wc -l `find /some/data/dir/with/text/files/ -type f` > report.txt

하지만 이로 인해 오류가 발생했습니다.

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

어쩌면 이 문제를 해결하는 더 좋은 방법이 있을까요?

어쩌면 GNU-Parallel이 여기서 도움을 줄 수 있을까요?

답변1

이를 사용하여 find파일 목록을 생성하고 계속해서 파이핑할 수 있습니다. 이렇게 하면 쉘이 단일 명령으로 500만 개의 파일 이름을 모두 확장하려고 시도하는 것을 방지할 수 있습니다.

LC_ALL=C find -type f -exec wc -l {} + |
    awk '
        $2 != "total" {
            if (max=="" || $1>max) {max=$1; mxf=$2};
            if (min=="" || $1<min) {min=$1; mnf=$2};
        }
        END { printf "Min %d for %s, max %d for %s\n", min, mnf, max, mxf }
    '

find목록을 생성하다파일 이름 계산awk, 스크립트 에 전달됩니다 . 이는 차례로 최대값과 최소값은 물론 파일 이름을 찾고 보고하는 힘든 작업을 수행합니다.

이 간단한 코드는 공백이나 인쇄할 수 없는 문자가 포함된 파일 이름을 처리하지 않습니다.

답변2

최신 버전의 GNU 유틸리티를 사용하세요:

(
  printf '/dev/null\0' # for the case where's there's only one file
  find . -type f -print0
) |
  wc --files0-from=- -l |
  sed '1d;$d' | # remove /dev/null and total
  sort -n |
  sed '1b;$b;d'

여기서는 인수를 전달하는 대신 파일 목록을 findstdin에서 stdin으로 파이프하므로 몇 가지 장점이 있습니다. 시스템 호출을 사용하지 않기 때문에 인수 수에 제한이 없습니다. 파일을 찾으면 해당 파일을 읽을 수 있습니다. or 솔루션과 비교하면 한 번의 호출만 수행되므로 최대 한 개의 행을 얻습니다.wcwcexecve()wcfindxargs-exec {} +wctotal

GNU wc8.30은 최소한 개행 문자가 포함된 파일 이름을 분리합니다. 예를 들어, 이름이 지정된 파일은 다음 ./a<newline>b과 같이 렌더링됩니다 './a'$'\n''b'(여기에서는 ksh93 스타일 $'...'인용을 사용하여 개행 문자를 로 나타냄 $'\n'). 이 경우 wc모든 파일 경로가 로 끝나야 수정이 이루어진 시기를 알 수 있습니다 .. 따라서 가 표시되면 '모양 변경이 수행되었음을 의미합니다.

매개변수 확장 플래그를 zsh사용하여 셸 에서 이 작업을 취소할 수 있습니다 .Q

$ wc -l './a
b'
146 './a'$'\n''b'
$ !! | read -r length file
$ printf '<%s>\n' $file ${(Q)file}
<'./a'$'\n''b'>
<./a
b>

일반적으로 이러한 손상이 언제 발생하는지 알 수 없습니다 wc. 예를 들어 동일한 파일 이름 a<newline>b이나 파일 이름이 렌더링됩니다.'a'$'\n''b'

$ wc -l 'a
b' "'a'$'\n''b'"
  146 'a'$'\n''b'
    1 'a'$'\n''b'
  147 total

답변3

xargs이 정확한 상황을 처리하기 위해 존재하며 관련된 파일 이름에 공백이나 줄 바꿈이 포함되지 않는 한 작동합니다.

find /some/data/dir/with/text/files/ -type f -print | xargs wc -l

그런 다음 행 수를 기준으로 정렬할 수 있습니다. 어떤 특정 파일에 최소 및 최대 줄 수가 포함되어 있는지 신경 쓰지 않으면 각 출력 줄에서 줄 수 필드를 추출하여 로 파이프한 uniq다음 첫 번째 줄이 최소 줄 수인 출력 파일을 생성할 수 있습니다. 행, 마지막으로 한 행이 최대 행 수입니다.

물론 여기에는 찾고 있는 정보를 계산하는 과정에서 많은 데이터가 유지되므로 파이프라인의 출력을 각 행을 실행한 다음 행당 개수가 있는지 추적하는 스크립트 find | xargs로 연결하는 것이 더 좋습니다. awk지금까지 본 최소값보다 작거나 지금까지 본 최대값보다 큽니다.

관련 정보