6

私は次のようなことをしようとしています:

for file in `find . *.foo`
do
somecommand $file
done

しかし、 $file が非常に奇妙であるため、コマンドは機能しません。私のディレクトリ ツリーには不適切なファイル名 (スペースを含む) があるため、findコマンドをエスケープする必要があります。しかし、明らかなエスケープはどれも 機能していないようです。-lsスペースで区切られたファイル名のフラグメント -fprintは、それ以上うまくいきません。

私も試し for file in "ました:*.foo -ls"; do echo $file; done - but that gives all of the responses from find in one long line.

ヒントはありますか?回避策があればうれしいのですが、これを理解できないことに不満を感じています。

ありがとう、アレックス

(こんにちはマット!)

4

6 に答える 6

9

その作業をシェルに頼るのではなく、find に頼ってください。

find . -name "*.foo" -exec somecommand "{}" \;

その後、ファイル名は適切にエスケープされ、シェルによって解釈されることはありません。

于 2009-04-15T21:34:58.323 に答える
2
find . -name '*.foo' -print0 | xargs -0 -n 1 somecommand

ただし、アイテムごとに多数のシェル コマンドを実行する必要がある場合は、面倒です。

于 2009-04-15T21:35:57.480 に答える
1

xargsはあなたの友達です。-0 (ゼロ) オプションも調査する必要があります。 find(with -print0) は、リストの作成に役立ちます。ウィキペディアのページには、いくつかの良い例があります。

を使用するもう 1 つの便利な理由xargsは、多数のファイル (数十個以上) がある場合、xargs がファイルを個別の呼び出しに分割し、xargs が呼び出されて実行されることです (最初のウィキペディアの例では、rm) 。

于 2009-04-15T21:35:40.350 に答える
1
find . -name '*.foo' -print0 | xargs -0 sh -c 'for F in "${@}"; do ...; done' "${0}"
于 2009-04-16T01:49:14.110 に答える
0

少し前に、ファイルの名前を変更して、Win32 環境で使用できるようにするために、似たようなことをしなければなりませんでした。

#!/bin/bash
IFS=$'\n'
function RecurseDirs
{
for f in "$@"
do
  newf=echo "${f}" | sed -e 's/[\\/:\*\?#"\|<>]/_/g'
  if [ ${newf} != ${f} ]; then
    echo "${f}" "${newf}"
    mv "${f}" "${newf}"
    f="${newf}"
  fi
  if [[ -d "${f}" ]]; then
    cd "${f}"
    RecurseDirs $(ls -1 ".")
  fi
done
cd ..
}
RecurseDirs .

これはおそらく少し単純化されており、名前の衝突を回避するものではなく、もっとうまくできると確信していますが、これにより、sed 置換を実行する前に検索結果 (私の場合) で basename を使用する必要がなくなります。

正確には、見つかったファイルに対して何をしているのですか?

于 2009-04-16T21:24:55.950 に答える