web-dev-qa-db-ja.com

bashスクリプトで検索の結果を処理するにはどうすればよいですか?

findコマンドを使用して、配列を使用してファイル名のリストを保存しようとしています。

何らかの理由で、学校で使用されているbashでアレイが機能しませんが、私のプログラムは自分のラップトップで動作します。

だから私はそれを行う別の方法があるかどうか疑問に思っていました、これは私が持っているものです:

array = (`find . -name "*.txt"`)  #this will store all the .txt files into the array

次に、catコマンドを使用して、配列項目にアクセスし、すべてのファイルのコピーを作成できます。

配列を使用せずにそれを行う別の方法はありますか?

57

次のようなものを使用できます。

find . -name '*.txt' | while read line; do
    echo "Processing file '$line'"
done

例えば。コピーを作成します。

find . -name '*.txt' | while read line; do
    echo "Copying '$line' to /tmp"
    cp -- "$line" /tmp
done

HTH

110
Johannes Weiss

JohannesWeißのソリューションで問題が発生していました。エコーを実行するだけで、ファイルの全リストで機能します。ただし、次の行でffmpegを実行しようとすると、スクリプトは最初に見つかったファイルのみを処理します。パイプが原因でIFSの面白いビジネスを想定していましたが、理解できず、代わりにforループで実行しました。

for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done
20
starpause

等号の前後に空白を入れないでください。

ar=($(find . -name "*.txt"))

可能であれば、バックティックは推奨されないため、避けます。特に質の悪いフォントでは、アポストロフィと混同されやすく、あまりうまくネストしません。

ほとんどの場合、-exec、-execdir、-ok、または-okdirを使用して検索結果を直接反復処理すると、最適なサービスが提供されます。

Forおよびwhileループは、ファイル名または改行とタブの空白に関しては正しく実行するのが困難です。

find ./ -name "*.txt" -exec grep {} ";"

{}はマスキングを必要としません。多くの場合、追加のプロセスを開始するfind/xargsの組み合わせが表示されます。

find ./ -name "*.txt" | xargs grep {} ";"
7
user unknown

Starpauseには最もクリーンなソリューションがあると思いますが、パスに空白があると失敗します。これは、IFSを設定することで修正されます。したがって、正しい答えは次のとおりです。

IFS=$'\n'
for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done
unset IFS

IFSの動作をリセットし、$IFS=$'\n'で必要な理由については、IFSを設定解除します。 https://unix.stackexchange.com/questions/184863/what- is-the-meaning-of-ifs-n-in-bash-scripting

5
beruic
find . -name '*.txt' | while IFS= read -r FILE; do
    echo "Copying $FILE.."
    cp "$FILE" /destination
done
3
ghostdog74