tar 파일의 폴더에 있는 파일 수를 반복적으로 계산합니다.

tar 파일의 폴더에 있는 파일 수를 반복적으로 계산합니다.

이전 질문을 더 확장하여 tar 파일의 파일 수를 계산했습니다(협회) 새로운 질문에tar 파일의 하위 폴더에 있는 파일 수를 계산하는 방법. 내가 원하는 마지막 것은 :

  1. 파일이 포함된 폴더 나열
  2. 파일 수 계산이내에그 폴더

나의 예tar 파일 목록 tar -tvf myfile.tar아래처럼 보인다(실제 tar 파일에는 더 많은 파일과 디렉토리가 있습니다). 총 2개의 폴더가 있으며 그 중폴더_파일_1그 안에는 3개의 파일이 있고,폴더_파일_2그 안에는 4개의 파일이 있습니다.

drwxrwxrwx someuser/users      0 2017-08-07 11:43 ./root_folder/subfolder/folder_files_1/
-rwxr-xr-x someuser/users 538962 2017-08-07 11:43 ./root_folder/subfolder/folder_files_1/i716266.MRDC.270
-rwxr-xr-x someuser/users 538962 2017-08-07 11:43 ./root_folder/subfolder/folder_files_1/i716267.MRDC.266
-rwxr-xr-x someuser/users 538944 2017-08-07 11:43 ./root_folder/subfolder/folder_files_1/i716268.MRDC.287
drwxrwxrwx someuser/users      0 2017-08-07 11:50 ./root_folder/subfolder/folder_files_2/
-rwxr-xr-x someuser/users 538696 2017-08-07 11:50 ./root_folder/subfolder/folder_files_2/i717157.MRDC.8
-rwxr-xr-x someuser/users 538694 2017-08-07 11:50 ./root_folder/subfolder/folder_files_2/i717158.MRDC.4
-rwxr-xr-x someuser/users 538692 2017-08-07 11:50 ./root_folder/subfolder/folder_files_2/i717159.MRDC.34
-rwxr-xr-x someuser/users 538696 2017-08-07 11:50 ./root_folder/subfolder/folder_files_2/i717160.MRDC.5

내가 검색한 가장 가까운 솔루션은 사용 awk후 나를 가리켰습니다 tar(참고자료 참조).여기그리고여기).

tar tvf myfile.tar | awk '/^d/ {print $0; /$6/; getline; file_no++} END {print file_no}'

/$6/해당 폴더를 일치시키면 됩니다 ./root_folder/subfolder/folder_files_1/. 하지만 이 파일에 포함된 파일 수를 정확하게 계산하는 것은 여전히 ​​불가능합니다.일치 디렉터리, 즉.폴더 file_1, 폴더 file_2.

내 코드를 수정하는 방법에 대한 제안 사항이 있나요?

답변1

또 다른 옵션:

tar tf archive.tar |
    awk '
        { if (gsub("[^/]+$", "")) { h[$0]++} }
        END { for (f in h) { printf "%d\t%s\n", h[f], f } }
    '

첫 번째 awk문은 파일 이름을 제거하고 결과 디렉터리 경로의 인스턴스 수를 계산합니다. 두 번째는 입력이 완전히 소비될 때 실행됩니다(예:표준 입력) 경로 목록과 해당 개수를 인쇄합니다.

원한다면 전체 내용을 한 줄로 통합할 수 있습니다(전체 내용을 연결하기만 하면 됩니다). 읽기 쉽도록 여기에서 나누었습니다.

tarball에 대해 실행한 결과:

4       ./root_folder/subfolder/folder_files_2/
3       ./root_folder/subfolder/folder_files_1/

답변2

tar -tvf file.tar | grep '^-' | wc -l

tar-(즉, 파일)로 시작하는 출력의 줄 수를 계산합니다 . 아카이브에 특별한 유형의 파일이 있는 경우 /^-"디렉터리를 제외한 모든 파일"을 계산하도록 변경하세요./^[^d]/

또 다른 방법은 다음과 같습니다 awk.

tar -tvf file.tar | awk '/^-/ { n++ } END { print n }'

7두 명령 모두 아카이브의 총 파일 수를 출력합니다 .


각 하위 폴더에 대해 별도의 개수를 원하는 경우:

tar -tvf file.tar | awk '/^d/ { d = $NF; next } { n[d]++ } END { for (d in n) print n[d], d }'

이것은 생성됩니다

4 ./root_folder/subfolder/folder_files_2/
3 ./root_folder/subfolder/folder_files_1/

귀하가 제공하는 데이터.

마지막 예제의 코드는 awk로 시작하는 모든 줄에서 디렉터리 이름을 선택 d하고 이를 연관 배열의 키로 사용합니다. 발견된 각 파일에 대해 배열 항목이 증가됩니다. 마지막으로 모든 항목과 해당 개수를 인쇄합니다.

답변3

GNU tar가 있다면,--to-command옵션:

--to-command=COMMAND
  Pipe extracted files to COMMAND.  The argument is the pathname
  of an external program, optionally with command line
  arguments.  The program will be invoked and the contents of
  the file being extracted supplied to it on its standard
  output.  Additional data will be supplied via the following
  environment variables:

  TAR_FILETYPE
         Type of the file. It is a single letter with the
         following meaning:

                 f           Regular file
                 d           Directory
                 l           Symbolic link
                 h           Hard link
                 b           Block device
                 c           Character device

         Currently only regular files are supported.
  ...
  TAR_FILENAME
         The name of the file.

이러한 변수를 사용하면 공백 등이 포함된 파일 이름을 안전하게 처리할 수 있습니다.

예를 들어, 쉘 문자열 대체를 사용하여 주어진 경로에서 파일 이름을 제거한 다음 sed를 사용하여 디렉토리가 아닌 경로만 인쇄한 다음 이를 정렬하고 적용하여 uniq -c개수를 얻을 수 있습니다.

tar xf foo.tar --to-command 'echo "$TAR_FILETYPE" "${TAR_FILENAME%/*}"' |
  sed -n '/^[^d]/s/^. //p' | 
  sort |
  uniq -c

GNU sed, sort 및 uniq가 있는 경우 해당 -z옵션을 사용하여 모든 파일 이름을 안전하게 처리할 수 printf "%s %s\0"있습니다 echo.

예:

% tar xf dev/pacaur/byobu/byobu_5.124.orig.tar.gz --to-command 'printf "%s %s\0" "$TAR_FILETYPE" "${TAR_FILENAME%/*}"' | sed -zn '/^[^d]/s/^. //p' | sort -z | uniq -zc | tr '\0' '\n'
     15 byobu-5.124
      2 byobu-5.124/Applications/Byobu.app/Contents
      1 byobu-5.124/Applications/Byobu.app/Contents/MacOS
      8 byobu-5.124/Applications/Byobu.app/Contents/Resources
      4 byobu-5.124/etc/byobu
      3 byobu-5.124/etc/profile.d
      1 byobu-5.124/experimental
     23 byobu-5.124/po
      1 byobu-5.124/snap
     38 byobu-5.124/usr/bin
     43 byobu-5.124/usr/lib/byobu
     18 byobu-5.124/usr/lib/byobu/include
      1 byobu-5.124/usr/share/appdata
      4 byobu-5.124/usr/share/byobu/desktop
     12 byobu-5.124/usr/share/byobu/keybindings
      4 byobu-5.124/usr/share/byobu/pixmaps
      1 byobu-5.124/usr/share/byobu/pixmaps/highcontrast
     11 byobu-5.124/usr/share/byobu/profiles
      4 byobu-5.124/usr/share/byobu/status
      3 byobu-5.124/usr/share/byobu/tests
      3 byobu-5.124/usr/share/byobu/windows
      3 byobu-5.124/usr/share/dbus-1/services
      4 byobu-5.124/usr/share/doc/byobu
     37 byobu-5.124/usr/share/man/man1
      1 byobu-5.124/usr/share/sounds/byobu

답변4

두 번 실행해도 괜찮다면(먼저 개수를 구한 다음 행 수를 구함) grep을 사용할 수 있습니다.

계산을 위해:

tar tvf myfile.tar | grep <path> | wc -l

줄의 경우 제거하십시오.| wc -l

한 번만 실행하려면 tar출력을 파일에 저장한 다음 catgrep 및 wc를 사용하면 됩니다. 전체 스크립트는 다음과 같습니다.

tmp_file=$(mktemp)
tar tvf myfile.tar > $tmp_file
cat $tmp_file | grep <subdir> | wc -l
cat $tmp_file | grep <subdir>
rm $tmp_file

한 줄짜리 코드를 원한다면 프로세스 대체 및 리디렉션을 사용하여 수행할 수 있지만 어떤 흐름으로든 실행하면 결국 스크립트/별칭/함수에 넣게 되므로 훨씬 쉽게 읽고 이해할 수 있습니다. .

tar 파일에서 여러 경로를 grep하려면 해당 경로를 모두 텍스트 파일에 넣고 다음을 사용할 수 있습니다.grep -f <paths file>

관련 정보