パラメータとしてファイルパスを要求するプログラムがあります。このパスは引用できず、作業ディレクトリに依存できません。複数の、、、、xargs
sを接続せずにこれを実行できますか?tr
find
readlink
"*.csv"ファイルの出力例:/home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
答え1
ファイルパスをコマンドに引数として渡すには、find
自分でやろう-exec
オプショントリックなしxargs
:
find /home/user -name '*.csv' -exec yourcommand '{}' +
その後、呼び出されたすべてのファイルを見つけて、見つかったすべての*.csv
ファイルを引数として実行します。見つかった各ファイルは個別の完全引数でプログラムに渡されるため、エスケープやその他の操作は必要ありません。各引数は、フルファイルパスである多くの引数を使用します。/home/user
yourcommand /home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv ...
yourcommand
別の方法はシェル(zsh
特に)は、次のように作成できる高度なワイルドカードをサポートします。
yourcommand **/*.csv
上記の効果も得られます。
文字列自体を本当にエスケープしたい場合、コマンドを直接実行する代わりにbash
'を使用できます。組み込みprintf
:
find /home/user -name '*.csv' -exec bash -c 'printf "%q " "$@"' dummy '{}' +
書式%q
指定は、文字列引数のシェルエスケープバージョンに拡張されます。多くのパラメータでは、printf
フォーマット文字列がすべてのパラメータに対して繰り返されるため、コマンド内のすべてのパラメータに対してスペースで終わるエスケープ文字列が生成されますbash -c
。dummy
の値として使用$0
し、(完全)ファイル名である残りの引数をすべて"$@"
指定します。printf
あなたの例では正確に/home/user/a\ b.csv /home/user/my\ dir/c\ d\$2.csv
。
答え2
そしてzsh
:
print -r -- **/*.csv(D:a:q)
改行、タブ、印刷できない文字などの一部の文字は記号を使用してレンダリングされるため、$'...'
問題になる可能性があります。
別の方法は次のとおりです。
print -r -- *.csv(e/'REPLY=${(qq)REPLY:a}'/)
すべてのファイルパスは一重引用符で囲まれています。