54

次のコマンドは、現在のディレクトリ内のすべてのファイルを列挙し*.txt、それらを1つずつ処理しようとします。

for line in "find . -iname '*.txt'"; do 
     echo $line
     ls -l $line; 
done

次のエラーが発生するのはなぜですか?:

ls: invalid option -- 'e'
Try `ls --help' for more information.
4

4 に答える 4

125

ファイル名のスペースと改行を処理するため、ファイルをループするより良い方法を次に示します。

#!/bin/bash

find . -type f -iname "*.txt" -print0 | while IFS= read -r -d $'\0' line; do
    echo "$line"
    ls -l "$line"    
done
于 2013-02-25T11:39:12.453 に答える
19

for-loop は、指定された文字列の (スペースで区切られた) 各エントリを反復処理します。

findコマンドを実際に実行するのではなく、文字列として指定します (-loop によって反復されforます)。二重引用符の代わりに、バッククォートまたは$():

for line in $(find . -iname '*.txt'); do 
     echo "$line"
     ls -l "$line"
done

さらに、ファイルのパス/名前にスペースが含まれている場合、このメソッドは失敗します (forループはスペースで区切られたエントリを反復するため)。代わりに、dogbanes answerで説明されている方法を使用することをお勧めします。


エラーを明確にするには:

前述のように、for line in "find . -iname '*.txt'"; スペースで区切られたすべてのエントリを反復処理します。

  • 探す
  • .
  • -いなめ
  • '*.txt' (私は思う...)

最初の 2 つは (望ましくない動作を除いて) エラーにはなりませんが、3 番目は実行時に問題があります。

ls -l -iname

多くの (bash) コマンドは 1 文字のオプションを組み合わせることができるため-iname、 と同じ-i -n -a -m -eです。そして出来上がり:あなたのinvalid option -- 'e'エラー!

于 2013-02-25T10:43:44.277 に答える
18

ファイル名にスペースと改行を使用した、よりコンパクトなバージョン:

find . -iname '*.txt' -exec sh -c 'echo "{}" ; ls -l "{}"' \;
于 2013-02-26T10:54:31.833 に答える
2

コマンドを文字列として渡す代わりに、引用符の代わりにコマンド置換を使用して find を実行します。

for line in $(find . -iname '*.txt'); do 
     echo $line
     ls -l $line; 
done
于 2013-02-25T10:42:25.350 に答える