2017-04-05 60 views
0

我想運行下面的bash命令爲每個文件夾中的每個文件(輸出每個處理.csv的唯一JSON文件),通過一個Makefile:Bash找到執行過程輸出重定向到每個不同的文件

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

這裏就是我管理,我與標準輸入/輸出語法和參數掙扎:

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

幫助非常感謝!

+1

順便說一句,最好避免使用'{}'作爲'find -exec'中的子字符串。 [POSIX'find'](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html)並不保證這種行爲可行,許多常見使用案例都有重大的安全警告(for實例中,'sh -c'mv {}/* ..''將會處理正在處理的文件名中''()'中的任何內容,就像它是代碼一樣)。 –

回答

1

您只傳遞一個參數到csvtojson - 要運行的文件名。

> outputfile根本不是論據;相反,它是一個指令,在實際啓動該命令之前,解析並調用相關命令以將命令的stdout連接到給定文件名。

因此,在運行find命令之前,重定向會被解析 - 因爲這是shell中唯一涉及的地方。

如果你想涉及外殼,考慮這樣做如下:

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

...或者,如下:

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

...或者,如果你想爲了能夠在循環內部設置shell變量並在退出後保留它們,可以使用process substitution來避免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

相關問題