2014-04-10 54 views
0

我有逗號分隔的txt文件,它必須只有五列,但某些行的列數超過5列。
我想把第6到第10個換成換行符,把第11個到第15個換成換行符等等。 和第6,第11屆16等列有空間deleimert而不是逗號
將分隔字段移動到帶有不同分隔符的換行符

下面是input.txt

111 1, 2, 3, 4, 5 
11 2, 13, 14, 15 5, 16 11, 17, 18, 19, 20 
22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 3333 3, 34 

下面的conetent是Output.txt

111 1, 2, 3, 4, 5 
11 2, 13, 14, 15 5, 16 
11, 17, 18, 19, 20 
22, 23, 24, 25, 26 
22, 27, 28, 29, 21 
30, 31, 32, 3333 3, 34 
+0

是否有可能存在在任何空間的'input.txt'比5和第6列,第10和第11列之間的空間等等等? – John1024

+1

'tr'''\ n' devnull

+0

我可以看到你更新的輸入 –

回答

1

的conetent在當前(第三個版本),它看起來像我們需要計算四個逗號,然後是一個更多的實體,後面跟着一個空格(不是逗號),然後在該點添加換行符。如果是這種情況,那麼使用:

$ sed 's/\(\([^,]\+,\)\{4\}[[:space:]]\+[[:alnum:]]\+\)[[:space:]]/\1\n/g' input.txt 
111 1, 2, 3, 4, 5 
11 2, 13, 14, 15 5, 16 
11, 17, 18, 19, 20 
22, 23, 24, 25, 26 
22, 27, 28, 29, 21 
30, 31, 32, 3333 3, 34 

如果您sed支持-r標誌(GNU),該命令的外觀可以略微提高:

sed -r 's/(([^,]+,){4}[[:space:]]+[[:alnum:]]+)[[:space:]]/\1\n/g' input.txt 

在OSX中,-r標誌不支持-E應改爲工作:

sed -E 's/(([^,]+,){4}[[:space:]]+[[:alnum:]]+)[[:space:]]/\1\n/g' input.txt 


解決方案這個問題的第二個版本

從給出的例子,我們需要插入一個換行符,每次列以空格結束而不是逗號。如果是這樣的話,則:

$ sed 's/\>[[:space:]]/\n/g' input.txt 
1, 2, 3, 4, 5 
12, 13, 14, 15, 16 
11, 17, 18, 19, 20 
22, 23, 24, 25, 26 
22, 27, 28, 29, 21 
30, 31, 32, 33, 34 

上述作品由尋找一個字,它sed表示由\>,隨後的任何類型的空白的端部。然後它用換行符替換那個空間。隨後用逗號代替的列被單獨留下。

sed substitute命令的格式爲s/old/new/如果我們想要替換第一個匹配項,或者如果我們想要替換所有這些匹配項,請輸入s/old/new/g。由於我們希望替換所有的事件,因此我們使用g。在上面的命令中,「舊」部分是\>[[:space:]],這意味着任何類型的空白結尾。 「新」部分僅代表換行符\n

sed還允許地方改變你的文件的選項:

sed -i 's/\>[[:space:]]/\n/g' input.txt 

-i選項告訴sed改變輸入文件中的位置。運行此命令後,將更新input.txt

+0

對不起@ John1024,我錯過了更新輸入格式 – Marjer

+0

@ GanzRicanz感謝澄清。看看修改後的答案。 – John1024

1

嘗試:

$ cat f1 
1,2,3,4,5 
12,13,14,15,16 11,17,18,19,20 
22,23,24,25,26 22,27,28,29,21 30,31,32,33,34 

$ awk '1' RS=' |\n' f1 
1,2,3,4,5 
12,13,14,15,16 
11,17,18,19,20 
22,23,24,25,26 
22,27,28,29,21 
30,31,32,33,34 

用戶更新的輸入以上Solution將不工作

$ cat f2 
1, 2, 3, 4, 5 
12, 13, 14, 15, 16 11, 17, 18, 19, 20 
22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 33, 34 

$ awk '{gsub(/, /,",");gsub(/ /,"\n");gsub(/,/,", ")}1' f2 

OR 

$ awk '{gsub(/[[:alnum:]] /,"&\n")}1' f2 

1, 2, 3, 4, 5 
12, 13, 14, 15, 16 
11, 17, 18, 19, 20 
22, 23, 24, 25, 26 
22, 27, 28, 29, 21 
30, 31, 32, 33, 34 

答到下面的評論

gsub(/, /,",")  # Substitute comma for comma + space 

gsub(/ /,"\n")  # So now (field + space + field) is left, substitute space with newline 

gsub(/,/,", ")  # substitute comma space (as you requested in expected output) for comma (first argument) 
+0

對不起@Akshay,我錯過了更新輸入格式 – Marjer

+0

@GanzRicanz我更新見上面 –

+0

你能解釋'awk'{gsub(/,/,「,」); gsub(/ /,「\ n」); gsub(/,/,「,」)} 1'' – Marjer

0

我沒有時間轉換f下面的腳本ROM KSH來砸,我將它作爲一個做法:

#!/bin/ksh 
splitline() { 
    echo $* | IFS=\, read f1 f2 f3 f4 f5 
    # remove first space 
    fx=${f5# } 
    echo ${fx} | read f5a f5b 
    echo "${f1},${f2},${f3},${f4}, ${f5a}" 
    if [[ -n "${f5b}" ]]; then 
     splitline ${f5b} 
    fi 
} 

cat input.txt | while read line; do 
    splitline $line 
done