ファイル名を印刷するときにforループのスペースを無視しますか?

ファイル名を印刷するときにforループのスペースを無視しますか?

サイズが1kより大きく、拡張子がtxtのファイルをインポートしようとしていますが、コードは次のようになります。

files=$(find foldername -size +1k -name \*.txt -exec {} \;)

for item in $files
do 
echo $item
done

ところで、以下のように予期せぬ結果が出ました。助けてください! ! !

DEST/sample - Copy - Copy.txt: line 1: Hello: command not found
DEST/sample - Copy - Copy.txt: line 2: This: command not found
DEST/sample - Copy - Copy.txt: line 3: In: command not found
DEST/sample - Copy - Copy.txt: line 4: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 5: User: command not found
DEST/sample - Copy - Copy.txt: line 6: -s: command not found
DEST/sample - Copy - Copy.txt: line 7: -d: command not found
DEST/sample - Copy - Copy.txt: line 8: -t: command not found
DEST/sample - Copy - Copy.txt: line 9: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 10: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 11: Hello: command not found
DEST/sample - Copy - Copy.txt: line 12: This: command not found
DEST/sample - Copy - Copy.txt: line 13: In: command not found
DEST/sample - Copy - Copy.txt: line 14: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 15: User: command not found
DEST/sample - Copy - Copy.txt: line 16: -s: command not found
DEST/sample - Copy - Copy.txt: line 17: -d: command not found
DEST/sample - Copy - Copy.txt: line 18: -t: command not found
DEST/sample - Copy - Copy.txt: line 19: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 20: Hello: command not found
DEST/sample - Copy - Copy.txt: line 21: This: command not found
DEST/sample - Copy - Copy.txt: line 22: In: command not found
DEST/sample - Copy - Copy.txt: line 23: $'\r': command not found
DEST/sample - Copy - Copy.txt: line 24: User: command not found
DEST/sample - Copy - Copy.txt: line 25: -s: command not found
DEST/sample - Copy - Copy.txt: line 26: -d: command not found
DEST/sample - Copy - Copy.txt: line 27: -t: command not found
DEST/sample - Copy.txt: line 1: Hello: command not found
DEST/sample - Copy.txt: line 2: This: command not found
DEST/sample - Copy.txt: line 3: In: command not found
DEST/sample - Copy.txt: line 4: $'\r': command not found
DEST/sample - Copy.txt: line 5: User: command not found
DEST/sample - Copy.txt: line 6: -s: command not found
DEST/sample - Copy.txt: line 7: -d: command not found
DEST/sample - Copy.txt: line 8: -t: command not found
DEST/sample - Copy.txt: line 9: $'\r': command not found
DEST/sample - Copy.txt: line 10: $'\r': command not found
DEST/sample - Copy.txt: line 11: Hello: command not found
DEST/sample - Copy.txt: line 12: This: command not found
DEST/sample - Copy.txt: line 13: In: command not found
DEST/sample - Copy.txt: line 14: $'\r': command not found
DEST/sample - Copy.txt: line 15: User: command not found
DEST/sample - Copy.txt: line 16: -s: command not found
DEST/sample - Copy.txt: line 17: -d: command not found
DEST/sample - Copy.txt: line 18: -t: command not found
DEST/sample - Copy.txt: line 19: $'\r': command not found
DEST/sample - Copy.txt: line 20: Hello: command not found
DEST/sample - Copy.txt: line 21: This: command not found
DEST/sample - Copy.txt: line 22: In: command not found
DEST/sample - Copy.txt: line 23: $'\r': command not found
DEST/sample - Copy.txt: line 24: User: command not found
DEST/sample - Copy.txt: line 25: -s: command not found
DEST/sample - Copy.txt: line 26: -d: command not found
DEST/sample - Copy.txt: line 27: -t: command not found

答え1

明らかな問題:findコマンドは、-exec {}見つかったすべてのファイルを実行しようとしているものを実行しています(ほとんどのエラーメッセージのソース)。たとえば、次の意味があります-print

files=$(find foldername -size +1k -name \*.txt -print)

名前にスペースが含まれているファイルが見つかると、リストに問題が発生する可能性があります。ただし、ファイルが正しく見つかったら、この問題を確認できます。

これを行う方法はいくつかあります。スクリプトを少し変更した方法は次のとおりです。

find foldername -size +1k -name \*.txt -print | \
while IFS= read -r item
do 
echo "$item"
done

答え2

-execそれがあなたが望むものであると仮定してください。 (このオプションは-execファイルを読み込むのではなくファイルを実行します)

findオプションと一致するファイル名を印刷する簡単な解決策は次のとおりです。

find foldername -size +1k -name \*.txt -print

変数に名前を割り当てる必要がある場合は、より多くの名前が必要です。コマンドで生成されたファイル名のスペースを処理できるようにするには、findこのオプションが一般-print0的なソリューションです。

find foldername -size +1k -name \*.txt -print0

しかし、結果をbash変数として読み込むのは簡単ではありません。
説明が長くなります。この素晴らしい Greg Wiki ページ

#!/bin/bash
unset a
while IFS= read -r -d $'\0' file; do
    a+=( "$file" )        # or however you want to process each file
done < <(find foldername -size +1k -name \*.txt -print0)

printf 'filename=%s\n' "${a[@]}"

答え3

を使用すると、見つかった各ファイルをコマンドとして実行するように-exec {} \;指示できます。findファイル名を印刷したいと思うので、次のように言います-printファイル名にスペースが含まれていると中断されます。lsorの出力を解析するのは一般的に悪い考えですfind。ファイル名にスペースやその他の特殊文字が含まれる可能性がまったくない場合にのみ、この操作を実行してください。

結果に基づいてアクションを実行する安全な方法は、アクションをfind実行することです。find特定のシェル構成(複数のコマンド、変数拡張、パイプなど)を使用する必要がある場合は、ifシェルを呼び出します。ファイル名をこのシェルに引数として渡します。

find … -exec sh -c '
  echo "$0"
' {} \;

各ファイルに対して 1 つのシェルを呼び出すのではなく、ファイルのバッチに対してシェルを呼び出すと、作業を高速化できます。

find … -exec sh -c '
  for item do
    echo "$item"
  done
' sh {} +

関連情報