このfind
コマンドのファイルパス
find . -printf "%p \n"
珍しい文字(スペース、バックスラッシュ、二重引用符など)をエスケープしないでください。
このオプションは-ls
エスケープされたパスを印刷しますが。ls -dils
printf
効率的なコマンドが必要なので、追加のコマンドを実行しても役に立たls
ず、すべての追加文字を印刷することもできません。
エスケープされたパスを出力する他の(エレガントな)方法はありますかfind
?
ベストアンサー1
find -exec
通常、すべてのファイル名に対して実行されるコマンドを使用したり、find -print0
NULLバイトで区切られたエントリを読み取ることができるいくつかのコマンド(たとえばxargs -0
)に名前をパイプしたいとします。
本当に引用された文字列が必要な場合、Bashにはこれを行うためのいくつかのオプションがあります。
$ find -exec bash -c 'printf "%s\n" "${@@Q}"' sh {} +
'./single'\''quote'
'./space 1'
$'./new\nline'
'./double"quote'
$ find -exec bash -c 'printf "%q\n" "$@"' sh {} +
./single\'quote
./space\ 1
$'./new\nline'
./double\"quote
これにはシェルへの追加呼び出しが必要ですが、単一のexecで複数のファイル名を処理するために使用できます。
許可ビット(ACLではない)の保存に関しては、次のことができます(GNU findから):
find -printf "%#m:%p\0" > files-and-modes
これにより、権限、コロン、ファイル名、および nul バイトを含む項目が出力されます(例:)。そうだろう0644:name with spaces\0
いいえ何でもエスケープして代わりにファイル名をそのまま印刷します(ただし、ターミナルに出力しない限り、この場合少なくとも改行がめちゃくちゃになります。)
Perlスクリプトを使用して結果を読み取ることができます。
perl -0 -ne '($m, $f) = split/:/, $_, 2; chmod oct($m), $f; ' < files-and-modes
または Bash では、ほとんどの説明を参照してください。
while IFS=: read -r -d '' mode file ; do
# do something useful
printf "<%s> <%s>\n" "$mode" "$file"
chmod "$mode" "$file"
done < files-and-modes
私がテストしたところによると、改行、引用符、スペース、コロンで動作します。IFS=" "
名前に後にスペースが含まれていると、設定に従ってスペースが削除されるため、スペース以外のものを区切り文字として使用する必要があります。