以前の質問をさらに拡張して、tarファイル内のファイル数を計算しました(協会)新しい質問にtarファイルのサブフォルダ内のファイル数を数える方法。私が望む最後のもの:
- ファイルを含むフォルダーのリスト
- ファイル数の計算以内にそのフォルダ
私の例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
ステートメントはファイル名を削除し、結果のディレクトリパスのインスタンス数を計算します。 2番目は、入力が完全に消費されたときに実行されます(例:標準入力)パスリストとその数を印刷します。
必要に応じて、コンテンツ全体を1行に統合できます(コンテンツ全体をリンクするだけです)。読みやすいようにここで分けました。
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
2回実行しても問題ない場合(最初に数を取得してから行数を取得する)、grepを使用できます。
計算のため:
tar tvf myfile.tar | grep <path> | wc -l
行の場合は削除します。| wc -l
一度だけ実行するには、tar
出力をファイルに保存してからcat
grepと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
1行のコードが必要な場合は、プロセスの置き換えとリダイレクトを使用して実行できますが、任意のフローで実行すると、最終的にスクリプト/エイリアス/関数に入れられるため、はるかに簡単に読みやすくなります。 。
tarファイルから複数のパスをgrepするには、そのパスをすべてテキストファイルに入れて、次のものを使用できます。grep -f <paths file>