2012-08-07 50 views
4

我想爲文本編輯做一個腳本。在這種情況下,我有一個名爲text.csv一個文本文件,其內容爲:使用shell腳本編輯文本格式

first;48548a;48954a,48594B 
second;58757a;5875b 
third;58756a;58576b;5867d;56894d;45864a 

我想使文本格式是這樣的:

first;48548a 
first;48954a 
first;48594B 
second;58757a 
second;5875b 
third;58756a 
third;58576b 
third;5867d 
third;56894d 
third;45864a 

什麼是命令我應該使用來實現這一目標?

+2

[你有什麼嘗試](http://whathaveyoutried.com)? – jordanm 2012-08-07 01:14:08

+0

在你的第一行輸入數據中,最後一個分隔符應該是逗號還是分號?或者你是否願意接受*或者*字符作爲分隔符? (答案可能會影響工具如何分割你的數據。) – ghoti 2012-08-07 01:18:32

+0

嗨喬丹,我只是嘗試使用awk命令,但我知道如何使它發生,所以我問我應該使用什麼命令..:D ..感謝您的幫助 – adhown 2012-08-07 02:40:07

回答

6

我會在awk中這樣做。

假設你的第一行應該有一個;代替,

$ awk -F\; '{for(n=2; n<=NF; n++) { printf("%s;%s\n",$1,$n); }}' input.txt 

未經檢驗。

1

awk -v FS=';' -v OFS=';' '{for (i = 2; i <= NF; ++i) { print $1, $i }}' 說明:AWK隱含地分割數據爲記錄(默認情況下由換行separeted,即線==記錄),然後被分成由下式給出字段分隔符(FS爲輸入字段分隔符和OFS用於輸出分離器)編號字段。 對於每個記錄,該腳本都會打印第一個字段(這是記錄名稱)以及第i個字段,而這正是您需要的。

2

這是一個純粹的bash解決方案,可同時處理,;

while IFS=';,' read -a data; do 
    id="${data[0]}" 
    data=("${data[@]:1}") 
    for item in "${data[@]}"; do 
     printf '%s;%s\n' "$id" "$item" 
    done 
done < input.txt 

更新 - 基於chepner的建議替代打印方法:

while IFS=';,' read -a data; do 
    id="${data[0]}" 
    data=("${data[@]:1}") 
    printf "$id;%s\n" "${data[@]}" 
done < input.txt 
+0

或'printf'$ id;%s \ n「」$ {data [@]}「';不需要for循環。 – chepner 2012-08-07 02:06:57

+0

@chepner - 這是一個很好的建議。我通常不喜歡在printf的格式字符串中擴展變量,但它確實保存了一個循環。 – jordanm 2012-08-07 02:10:05

1
while IFS=';,' read -a data; do 
    id="${data[0]}" 
    data=("${data[@]:1}") 
    printf "$id;%s\n" "${data[@]}" 
done < input.txt 

awk -v FS=';' -v OFS=';' '{for (i = 2; i <= NF; ++i) { print $1, $i }}' 

而且

$ awk -F\; '{for(n=2; n<=NF; n++) { printf("%s;%s\n",$1,$n); }}' input.txt 

謝謝大家的建議,:d。這真的給了我一個新的知識..

+1

如果您要回答自己的問題,則應包含尚未發佈爲答案的內容。而不是重新發布答案,你應該upvote他們,並選擇一個「接受」。請閱讀[FAQ](http://stackoverflow.com/faq)。 – jordanm 2012-08-07 15:10:25