24
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について知っています-私はそれを行う方法があるかもしれません、それはスペースを含むファイル名を進めるときにエラーにつながるかもしれません。どんなガイダンスでも大歓迎です。

4

8 に答える 8

49
find . -name "filename including space" -print0 | 
  xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt; rm -rdf {}'

ちょうど今これに出くわしました、そして私達はより少ない頻度でシェルを呼び出すことができます:

find . -name "filename including space" -print0 | 
  xargs -0 sh -c '
      for file; do
          ls -aldF "$file" >> log.txt
          rm -rdf "$file"
      done
  ' sh

末尾の「sh」はシェルで$0になります。ファイル(から取得)をコマンドラインパラメーターとしてシェルにxargs提供します。forループを使用してファイルを反復処理します。find

于 2011-09-19T15:51:05.727 に答える
16

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
于 2011-09-19T15:03:01.083 に答える
5

私はこれらすべての答えが今までにこの問題を解決する正しい方法を与えたと信じています。そして、私はJonathanの2つのソリューションとGlennの方法を試しましたが、これらはすべて私の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 {}'
于 2011-09-20T00:00:17.927 に答える
4

ファイル名に改行が含まれていない限り、GNUParallelには-print0は必要ありません。

find . -name "My brother's 12\" records" | parallel ls {}\; rm -rdf {} >log.txt

詳細については、紹介ビデオをご覧ください:http ://www.youtube.com/watch?v=OpaiGYxkSuQ

于 2011-09-20T17:06:37.867 に答える
2

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"
于 2015-10-14T18:14:25.147 に答える
1

の代わりにfind使用した後、複数のコマンドを実行できます。forxargs

IFS=$'\n'
for F in `find . -name "filename including space"`
do
    ls -aldF $F > log.txt
    rm -rdf $F
done

IFS内部フィールドセパレータを定義します。デフォルトは<space><tab><newline>です。ファイル名にスペースが含まれている可能性がある場合は、上記のように再定義することをお勧めします。

于 2014-07-15T10:16:19.110 に答える
1

パーティーに遅れましたが、ここで取り上げなかったもう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:

  1. 私はbash構文のいくつかの要素(「export-f」など)を使用していますが、これは他のシェルにも適応すると思います。
  2. これを初めて試したときは、ダミーの引数を追加しませんでした。代わりに、関数内の引数行に「 $ 0 」を追加しました(例: ls -aldf "$ 0" "$ @")。悪いアイデア。文体の問題は別として、「find」コマンドが何も返さない場合は壊れます。その場合、$ 0は「bash」に設定されます。代わりにダミー引数を使用すると、これらすべてが回避されます。
于 2016-03-27T02:37:29.500 に答える
0

別の解決策:

find . -name "filename including space" -print0 \
| xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"
于 2011-09-19T15:50:41.267 に答える