find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt
find . -name "filename including space" -print0 | xargs -0 rm -rdf
これらの2つのコマンドを1つに組み合わせて、2つではなく1つの検索のみを実行することは可能ですか?
私はxargsを知っています-スペースを含むファイル名を処理するときにエラーを引き起こす可能性のある方法があるかもしれません。どんなガイダンスも大歓迎です。
find
を複数回実行しないようにする場合は、tee
の直後にfind
を実行して、find
出力をファイル、次のように行を実行します。
find . -name "filename including space" -print0 | tee my_teed_file | xargs -0 ls -aldF > log.txt
cat my_teed_file | xargs -0 rm -rdf
これと同じことを達成する別の方法(実際に達成したい場合)は、find
の出力を変数に格納することです(TBでない場合)データの):
founddata=`find . -name "filename including space" -print0`
echo "$founddata" | xargs -0 ls -aldF > log.txt
echo "$founddata" | xargs -0 rm -rdf
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt; rm -rdf {}'
私はこれらのすべての答えがこの問題を解決する正しい方法を示していると信じています。そして、私はJonathanとGlennの方法の2つのソリューションを試してみました。これらはすべて、私のMac OS Xではうまく機能しました。mouvicielの方法は、おそらくいくつかの構成上の理由により、私のOSでは機能しませんでした。そして、それはジョナサンの2番目の方法に似ていると思います(私は間違っているかもしれません)。
グレンの方法へのコメントで述べたように、少しの微調整が必要です。だからここに私が試したコマンドが完璧に機能しました:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} | tee -a log.txt ; rm -rdf {}'
またはGlennの提案どおり:
find . -name "filename including space" -print0 |
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt ; rm -rdf {}'
ファイル名に改行がない限り、GNU Parallelに-print0は必要ありません。
find . -name "My brother's 12\" records" | parallel ls {}\; rm -rdf {} >log.txt
詳細については、紹介動画をご覧ください: http://www.youtube.com/watch?v=OpaiGYxkSuQ
恐ろしいxargs
アプローチのバリエーションだけで-print0
およびxargs -0
、これは私がそれを行う方法です:
ls -1 *.txt | xargs --delimiter "\n" --max-args 1 --replace={} sh -c 'cat {}; echo "\n"'
脚注:
xargs
には短いオプションがありますが、読者の理解のために長いオプションを使用しました。ls -1
再帰しない動作が必要な場合find -maxdepth 1 -iname "*.txt"
これはもう少し冗長です。私はパーティーに遅れましたが、ここで取り上げられなかったもう1つの解決策があります。ユーザー定義関数です。 1行に複数の命令を置くのは扱いにくく、読みにくく、保守が難しい場合があります。上記のforループはそれを回避しますが、コマンドラインの長さを超える可能性があります。
ここに別の方法があります(テストされていません)。
function processFiles {
ls -aldF "$@"
rm -rdf "$@"
}
export -f processFiles
find . -name "filename including space"` -print0 \
| xargs -0 bash -c processFiles dummyArg > log.txt
これは、私に多くの悲しみを与えた "dummyArg"を除いて、非常に簡単です。この方法でbashを実行すると、引数が読み込まれます
"$0" "$1" "$2" ....
期待の代わりに
"$1" "$2" "$3" ....
ProcessFiles {}は最初の引数が "$ 1"であると想定しているため、ダミー値を "$ 0"に挿入する必要があります。
Footnontes:
find
の代わりにfor
を使用すると、xargs
の後に複数のコマンドを実行できます。
IFS=$'\n'
for F in `find . -name "filename including space"`
do
ls -aldF $F > log.txt
rm -rdf $F
done
IFS
は内部フィールド区切り文字を定義します。デフォルトは<space> <tab> <newline>です。ファイル名にスペースが含まれている可能性がある場合は、上記のように再定義することをお勧めします。
別の解決策:
find . -name "filename including space" -print0 \
| xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"