2012-12-04 68 views
1

我有一個包含逗號分隔列的表格,我想將指定列中的逗號分隔值分隔爲新行。例如,給定的表是單獨逗號分隔的單元格與使用shell腳本的新行

Name Start Name2 

A 1,2 X,a 

B 5 Y,b 

C 6,7,8 Z,c 

,我需要逗號分隔值列2分離,以獲得低於

Name Start Name2 

A 1 X,a 

A 2 X,a 

B 5 Y,b 

C 6 Z,c 

C 7 Z,c 

C 8 Z,c 

表我想知道是否有與shell腳本的任何解決方案,這樣我就可以創建一個工作流程管道。

注意:原始表格可能包含多於3列。

+0

[當你嘗試](http://whathaveyoutried.com/)自己解決這個問題,你遇到了什麼問題?爲什麼Bash? – Johnsyweb

+0

我希望將輸出轉換爲其他命令,與在R中執行相比,它會節省一些時間,然後返回。 – Runner

回答

0

假設你的輸入和輸出的格式並沒有改變:

awk 'BEGIN{FS="[ ,]"} {print $1, $2, $NF; print $1, $3, $NF}' input_file 

輸入

input_file

A 1,2 X  
B 5,6 Y 

輸出

A 1 X 
A 2 X 
B 5 Y 
B 6 Y 

說明

  • awk:調用awk,用於操縱線(記錄)的工具和字段
  • '...':由單引號內容被提供給awk作爲指令
  • 'BEGIN{FS="[ ,]"}:在讀取任何行之前,請告訴awk使用空格和逗號作爲分隔符; FS代表場分隔符。
  • {print $1, $2, $NF; print $1, $3, $NF}:對於每個輸入行的讀取,在一行上打印第一個,第二個和最後一個字段,然後在下一行打印第一個,第三個和最後一個字段。 NF代表字段數,因此$NF是最後一個字段。
  • input_file:將輸入文件的名稱作爲參數提供給awk。

針對更新的輸入格式:

awk 'BEGIN{FS="[ ,]"} {print $1, $2, $4","$5; print $1, $3, $4","$5}' input_file 
+0

謝謝!我可以指定包含逗號分隔值的列嗎?該表可能包含多於3列。 – Runner

+0

@Runner你是什麼意思?你可以給你一些用例作爲原始問題的編輯嗎? (具體的例子很好,因爲它可以幫助定義你的問題的角落案例) –

+0

非常感謝你的答案。現在我修改了我的問題。對困惑感到抱歉。 – Runner

0

另一種方法可能看起來像這樣原來的問題的亞軍的修改後:

#!/bin/sh 

# Usage $0 <file> <column> 
# 

FILE="${1}" 

COL="${2}" 

# tokens separated by linebreaks 
IFS=" 
" 

for LINE in `cat ${FILE}`; do 
    # get number of columns 
    COLS="`echo ${LINE} | awk '{print NF}'`" 

    # get actual field by COL, this contains the keys to be splitted into individual lines 
    # replace comma with newline to "reuse" newline field separator in IFS 
    KEYS="`echo ${LINE} | cut -d' ' -f${COL}-${COL} | tr ',' '\n'`" 

    COLB=$((${COL} - 1)) 
    COLA=$((${COL} + 1)) 

    # get text from columns before and after actual field 
    if [ ${COLB} -gt 0 ]; then 
      BEFORE="`echo ${LINE} | cut -d' ' -f1-${COLB}` " 
    else 
      BEFORE="" 
    fi 

    AFTER=" `echo ${LINE} | cut -d' ' -f${COLA}-`" 

    # echo "-A: $COLA ($AFTER) | B: $COLB ($BEFORE)-" 

    # iterate keys and re-build original line 
    for KEY in ${KEYS}; do 
      echo "${BEFORE}${KEY}${AFTER}" 
    done 
done 

有了你可能這個shell文件做你想做的事。這會將第2列分成多行。

./script.sh input.txt 2 

如果想通過輸入雖然標準使用輸入管道(例如,在一氣呵成分割多個列),你可以改變6。行:

if [ "${1}" == "-" ]; then 
    FILE="/dev/stdin" 
else 
    FILE="${1}" 
fi 

並運行它這樣:

./script.sh input.txt 1 | ./script.sh - 2 | ./script.sh - 3 

注意即削減約場分離非常sensitiv。因此,該行以空格字符開始,第1列將是「」(空)。如果這些字段是由空格和製表符分隔的,則該腳本也會有其他問題。在這種情況下(如上所述)過濾輸入資源(以便字段僅由一個空格字符分隔)應該這樣做。如果這不可能或者每列中的數據都包含空格字符,那麼腳本可能會變得更加複雜。

相關問題