find
パフォーマンス上の理由から、多数のファイルを一覧表示し、各行にカウンタを含めるために使用したいと思います。これまでに私が持っていたものは次のとおりです。
local root_dir="."
local ouptut_file="/tmp/foo.txt"
File_Number=99 ## Initial value
echo "" > "${ouptut_file}" ## Initialize file to empty
find "$root_dir" \
-type f \
-depth 2 \
-name '*.xxx' \
-print0 \
| sort -z \
| xargs -0 printf "DoSomething %5d '%s'\n" $[File_Number++] -- \
> "${ouptut_file}"
この出力
DoSomething 99 '--'
DoSomething 0 'dirA/dirB/file1.xxx'
DoSomething 0 'dirA/dirB/file2.xxx'
DoSomething 0 'dirA/dirB/file3.xxx'
私が望むもの
DoSomething 100 'dirA/dirB/file1.xxx'
DoSomething 101 'dirA/dirB/file2.xxx'
DoSomething 102 'dirA/dirB/file3.xxx'
カウンタを含み、出力から最初の偽の線を削除するにはどうすればよいですか?
システムbash
:現在、macOS Ventura 13.0.1で使用中です。
ベストアンサー1
いくつかの注意:
$[...]
それは非常に古い算術拡張です。今日のbash文書にはこれについての言及さえありません。代わりに使用してください$((...))
。xargs
このコマンドを呼び出すたびに新しいプロセスが開始されるため、変数の1つを変更しても他の呼び出しには影響しません。- forは
printf(1)
他の--
パラメータと同じです。何が起こったら、型文字列の要件を満たすためにパラメータをxargs
実行してprintf "DoSomething %5d '%s'\n" $[File_Number++] dirA/dirB/file1.xxx dirA/dirB/file2.xxx ...
繰り返します。printf
したがって、各代替ファイル名は実際に数値として扱われて0
出力されます。
次のようなものを使用したい場合があります。
find "$root_dir" \
-type f \
-depth 2 \
-name '*.xxx' \
-print0 \
| sort -z \
| while read -r -d '' file; do
printf "DoSomething %5d '%s'\n" $((File_Number++)) "$file"
done > "${ouptut_file}"
また、実際にこれを使用してシェルで実行されているコマンドを印刷する場合は、正しく引用するのではなく%q
使用する必要があります。'%s'
からhelp printf
:
標準の printf(1) 形式に加えて、 %b はその引数からバックスラッシュエスケープシーケンスを拡張することを意味し、 %q はシェル入力として再利用できる方法で引数を引用することを意味します。