2016-09-13 19 views
0

我想將一個文件夾中的多個CSV文件的第二列合併到一個CSV文件中(逐列)。我失敗了。當我嘗試合併剪切第一列時(通過放置-f1),但是當我嘗試使用第二列(-f2)時,它只是弄得一團糟。不能找出原因。在這裏我的代碼在git中合併多重CSV文件的第二列BASH

for i in $FILES; 
do 
paste -d, final_table.csv <(cut -d',' -f 2 --complement "$i") > final_table_intermediate.csv; mv final_table_intermediate.csv final_table.csv ; 

done 

在此先感謝 埃米利亞諾

CSV file header

+0

亂成什麼意思?如果你想確實獲得第二列(而不是除第二列之外的所有內容),爲什麼要使用'--complement'? – chw21

+0

如果您使用的是CSV文件,我強烈建議使用csvkit - 這是一套CLI工具,可以使腳本編寫更容易。 –

+0

非常感謝你們! chw21我會嘗試你的代碼。如果我不使用補充,它將合併列1和列2,並將它用作合併文件中的列:( – Emiliano

回答

1

我得看看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} 

下面是我這假定所有的文件確實有至少儘可能多的列,你想讀的原始版本:

  1. 不滿意我的解決方案,因爲你一遍又一遍地打開同一文件進行讀取和同時寫作。我很想知道一種將未知數量的進程的輸出作爲不同輸入流傳遞到單個最終進程的方法。
  2. 在您的描述中,您需要第二列,但是您使用--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 

如果這是你得到了什麼而不是你想要什麼,告訴我如何輸出文件應與這些輸入文件的樣子。如果這不是你所得到的,請使用我的文件在系統上運行它並告訴我你得到了什麼。

+0

顯然,我不能讓它工作:(我認爲合併所有的第一行中的所有CSV文件的所有第一個單元格和第二行中的所有第二個單元格等等......任何線索? – Emiliano

+0

我已經更新了我的答案與輸入我使用的文件和我得到的輸出,請將它與你想要和/或得到的結果進行比較 – chw21

+0

啊,這太令人沮喪了!如果我選擇第1列,那麼代碼完美無缺,但如果選擇第2列, 「再次。順便說一句,我的文件只有2列,我在後更新中附加了標題,可能是第2列結構中的一些問題嗎?乾杯 – Emiliano