2017-04-05 7 views
0

Makefileを使用して、フォルダ内のすべてのファイルに対して次のbashコマンドを実行します(処理済み.csvごとに一意のJSONファイルを出力します)。Bash findファイルごとに異なるファイルにリダイレクトされた出力

csvtojson ./file/path.csv > ./file/path.json 

はここで、Iは、標準入力/アウト構文と引数に苦しんだ私が管理しているのです:

find ./ -type f -name "*.csv" -exec csvtojson {} > {}.json \; 

ヘルプははるかに高く評価します!

+1

一般に、 'find -exec'の部分文字列として' {} 'を使用するのが最善です。 [POSIX 'find'](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html)は、その動作がうまくいくことを保証するものではなく、多くの一般的な使用事例で重大なセキュリティ上の注意点があります。 'sh -c 'mv {}/* ..''は、コードであるかのように処理されているファイル名内の '$()'の中の何かを扱います。 –

答えて

1

実行するファイル名は、csvtojsonに1つのみの引数を渡しています。

> outputfileはまったく引数ではありません。その代わりに、実際にコマンドを開始する前に、コマンドのstdoutを指定されたファイル名に接続するために関連するコマンドを解析して呼び出すシェルへの指示です。

したがって、上記のリダイレクトは、コマンドが実行される前に解析されます。これは、シェルが関与する唯一の場所だからです。あなたがしたい場合は、

find ./ -type f -name '*.csv' -print0 | 
    while IFS= read -r -d '' filename; do 
    csvtojson "$filename" >"$filename.json" 
    done 

を...か:あなたはシェルが関与するをしたい場合

は、次のようにそう考える:

find ./ -type f -name "*.csv" \ 
    -exec sh -c 'for arg; do csvtojson "$arg" >"${arg}.json"; done' _ {} + 

を...または、次のようにループ内にシェル変数を設定して終了後もシェル変数を保持できるようにするには、を使用して、BashFAQ #24に記載されている問題を避けることができます。

bad=0 
good=0 
while IFS= read -r -d '' filename; do 
    if csvtojson "$filename" >"$filename.json"; then 
    ((++good)) 
    else 
    ((++bad)) 
    fi 
done < <(find ./ -type f -name '*.csv' -print0) 

echo "Converting CSV files to JSON: ${bad} failures, ${good} successes" >&2 

UsingFind、特にComplex Actions部とActions In Bulkのセクションを参照します。

+0

包括的な回答と参考に感謝します! – amigolargo

+1

問題ありません!私は、知識ベースに既に存在する主題に関する既存の質問があると予想していましたが、迅速な検索では不幸な答えが出てくるだけで、時には珍しい細部や注意点がありました。問題についてきれいで答えやすい質問を書いてくれてありがとう。 :) –

+0

こんにちは、心配しないでください。マニュアルとこれらの3つのオプションでちょっと時間を費やすつもりです。 – amigolargo

関連する問題