我得看看csvkit,由@建議海登 - 希夫
如果你不」不想走這條路,這就是我想出的。 雖然有幾個注意事項:
更新:你的編輯說明你的輸入文件並不總是有兩列,而我還沒有找到一種方法,使cut
返回一個空字符串(但新行)使舊版本工作。
所以現在我要通過行的CSV線,抓住值(或空字符串)到每個輸入文件一個臨時文件,然後將其粘貼他們一起在最後:
#!/usr/bin/env bash
FILES="infile_??.csv"
FINAL="final_table.csv"
COLUMN="3"
# Delete ${FINAL} if it exists.
[[ -f "${FINAL}" ]] && rm ${FINAL}
TMPFILES=""
for f in ${FILES}; do
while IFS='' read -r line || [[ -n "$line" ]]; do
val=$(cut -f ${COLUMN} -d, -s <<< $line)
[[ -n "${val}" ]] && echo "${val}" || echo " "
done < "${f}" > "${f}.${COLUMN}.csv"
TMPFILES="${TMPFILES} ${f}.${COLUMN}.csv"
done
paste -d, ${TMPFILES} > ${FINAL}
rm ${TMPFILES}
下面是我這假定所有的文件確實有至少儘可能多的列,你想讀的原始版本:
- 不滿意我的解決方案,因爲你一遍又一遍地打開同一文件進行讀取和同時寫作。我很想知道一種將未知數量的進程的輸出作爲不同輸入流傳遞到單個最終進程的方法。
- 在您的描述中,您需要第二列,但是您使用
--complement
選項,該選項返回除第二列之外的所有內容。這讓我有點失望。我無視這一點,並按照你的描述走。
所以在這裏,它是:
#!/usr/bin/env bash
FILES="infile_??.csv"
FINAL="final_table.csv"
COLUMN="2"
# Delete ${FINAL} if it exists.
[[ -f "${FINAL}" ]] && rm ${FINAL}
for f in $FILES; do
if [[ -f ${FINAL} ]]; then
# ${FINAL} already exists from an earlier iteration
# If you have "moreutils" installed, you can use sponge:
# cut -d',' -f 2 ${f} | paste -d',' ${FINAL} - | sponge ${FINAL}
# otherwise you can use "echo" in the way below:
echo "$(cut -d',' -f ${COLUMN} ${f} | paste -d',' ${FINAL} -)" > ${FINAL}
else
# ${FINAL} does not yet exist, we have to create it.
cut -d',' -f ${COLUMN} ${f} > ${FINAL}
fi
done
更新:我的理解是,應採取每個輸入文件的第二列,並將其寫入列後列到輸出文件中,就像這樣:
我的輸入文件:
infile_01.txt
:
111, 112, 113
121, 122, 123
131, 132, 133
141, 142, 143
infile_02.txt
:
211, 212, 213
221, 222, 223
231, 232, 233
241, 242, 243
(因此,每個數爲100 *(文件中沒有)+ 10 *(行無)+(列中沒有)。)
我的代碼,我的電腦上,產生這樣的輸出:
112, 212
122, 222
132, 232
142, 242
如果這是你得到了什麼而不是你想要什麼,告訴我如何輸出文件應與這些輸入文件的樣子。如果這不是你所得到的,請使用我的文件在系統上運行它並告訴我你得到了什麼。
亂成什麼意思?如果你想確實獲得第二列(而不是除第二列之外的所有內容),爲什麼要使用'--complement'? – chw21
如果您使用的是CSV文件,我強烈建議使用csvkit - 這是一套CLI工具,可以使腳本編寫更容易。 –
非常感謝你們! chw21我會嘗試你的代碼。如果我不使用補充,它將合併列1和列2,並將它用作合併文件中的列:( – Emiliano