2017-06-30 45 views
1

給定文件foo.txt包含文件名,如分隔符:使用sed的類似削減

2015_275_14_1,Siboney_by_The_Tailor_Maids 
2015_275_16_1,Louis_Armstrong_Cant_Give_You_Anything_But_Love 
2015_275_17_1,Benny_Goodman_Trio_Nice_Work_Avalon 
2015_275_18_1,Feather_On_Jazz_Jazz_In_The_Concert_Hall 
2015_235_1_1,Integration_Report_1 
2015_273_2_1_1,Cab_Calloway_Home_Movie_1 
2015_273_2_2_1,Cab_Calloway_Home_Movie_2 

我要替換與.逗號之前的部分_,並在第二部分_後帶空格的逗號。

我可以單獨完成每個:

sed -E -i '' 's/([0-9]{4})_([0-9]{3})_([0-9]{2})_([0-9])/\1.\2.\3.\4./' 

的第一部分,第二部分則有:

sed -E -i '' "s/_/ /g" 

,但我希望通過使用來完成它在一個更簡單的方式用sed切但不起作用:

cut -d "," -f 1 foo.txt | sed -E -i '' "s/_/./g" foo.txt && cut -d "," -f 2 foo.txt | sed -E -i '' "s/_/ /g" foo.txt

不好。

那麼,有沒有辦法用sed也許awk或者也可以是別的地方我治療,作爲分隔符,如cut做到這一點?

所需的輸出:

2015.275.14.1,Siboney by The Tailor Maids 
+0

您可能會得到所需要的輸出更詳細的信息。 – CWLiu

+0

@CWLiu好的。完成 – Bleakley

回答

1

@CWLiu的答案類似,但我使用OFS(輸出字段分隔符),而不是在逗號中加回,並且必須使用printf添加換行符。

awk -F ',' 'BEGIN {OFS = FS} {gsub(/_/, ".", $1); gsub(/_/, " ", $2); print;}' foo.txt 

說明:

-F ','設置字段分隔符

BEGIN {OFS = FS}設置輸出字段分隔符(缺省空間)等於字段分隔符所以逗號打印背出

gsub("_", ".", $1)全球第一列替換

第二列全局替換

print打印整條生產線

+1

謝謝! @dosentmatter優秀的解釋!還要感謝edmorton,benjaminw和CWliu提供的答案。每個人都很棒! – Bleakley

+1

只要知道'gsub()'的第一個參數是一個正則表達式,而不是一個字符串,所以代碼應該使用正則表達式分隔符('/.../')而不是字符串分隔符('「...」 )。 –

+0

謝謝埃德,我編輯了答案。我是awk noob。 – dosentmatter

2

您可以使用awk達到你的目標,這裏的方法。

$ awk -F',' '{gsub(/_/,".",$1);gsub(/_/," ",$2);printf "%s,%s\n",$1,$2}' file                          
2015.275.14.1,Siboney by The Tailor Maids 
2015.275.16.1,Louis Armstrong Cant Give You Anything But Love 
2015.275.17.1,Benny Goodman Trio Nice Work Avalon 
2015.275.18.1,Feather On Jazz Jazz In The Concert Hall 
2015.235.1.1,Integration Report 1 
2015.273.2.1.1,Cab Calloway Home Movie 1 
2015.273.2.2.1,Cab Calloway Home Movie 2 
+0

謝謝@CWLiu每個人都很棒! – Bleakley

+0

@Bleakley,如果問題得到解決,您可以選擇接受答案。 – CWLiu

1

你可以cutpaste

$ paste -d, <(cut -d, -f1 infile | sed 'y/_/./') <(cut -d, -f2 infile | sed 'y/_/ /') 
2015.275.14.1,Siboney by The Tailor Maids 
2015.275.16.1,Louis Armstrong Cant Give You Anything But Love 
2015.275.17.1,Benny Goodman Trio Nice Work Avalon 
2015.275.18.1,Feather On Jazz Jazz In The Concert Hall 
2015.235.1.1,Integration Report 1 
2015.273.2.1.1,Cab Calloway Home Movie 1 
2015.273.2.2.1,Cab Calloway Home Movie 2 

的進程替換<()可以讓你把命令的輸出就像一個文件,paste -d,膏每個命令並排側的輸出,分離以逗號分隔。

sed y命令音譯字符,在這種情況下,相當於s/_/./g。和s/_/ /g

你也可以這樣做純粹是在中美戰略經濟對話,但它是一個有點笨拙:

sed 'h;s/.*,//;y/_/ /;x;s/,.*//;y/_/./;G;s/\n/,/' infile 

解釋:

h   # Copy pattern space to hold space 
s/.*,// # Remove first part including comma 
y/_// # Replace all "_" by spaces in the remaining second part 
x   # Swap pattern and hold space 
s/,.*// # Remove second part including comma 
y/_/./ # Replace all "_" by periods in the remaining first part 
G   # Append hold space to pattern space 
s/\n/,/ # Replace linebreak with comma 

,或者(從評論由potong):

sed 's/,/\n/;h;y/_/ /;x;y/_/./;G;s/\n.*\n/,/' infile 

說明:

s/,/\n/  # Replace comma by linebreak 
h   # Copy pattern space to hold space 
y/_//  # Replace all "_" by spaces 
x   # Swap pattern and hold space 
y/_/./  # Replace all "_" by periods 
G   # Append hold space 
s/\n.*\n/,/ # Remove second and third line in pattern space 
+0

謝謝@本傑明! – Bleakley

+0

sed解決方案的替代方案可能是:'sed's /,/ \ n /; h; y/_//;x;y/_/./;G;s/\n.*\n/, /'文件' – potong

+0

@potong不錯,讓我補充一點! –

1
$ awk 'BEGIN{FS=OFS=","} {gsub(/_/,".",$1); gsub(/_/," ",$2)} 1' file 
2015.275.14.1,Siboney by The Tailor Maids 
2015.275.16.1,Louis Armstrong Cant Give You Anything But Love 
2015.275.17.1,Benny Goodman Trio Nice Work Avalon 
2015.275.18.1,Feather On Jazz Jazz In The Concert Hall 
2015.235.1.1,Integration Report 1 
2015.273.2.1.1,Cab Calloway Home Movie 1 
2015.273.2.2.1,Cab Calloway Home Movie 2 
+1

謝謝@edmorton! – Bleakley

1

嘗試此GNU sed

$ cat input.txt 
2015_275_14_1,Siboney_by_The_Tailor_Maids 
2015_275_16_1,Louis_Armstrong_Cant_Give_You_Anything_But_Love 
2015_275_17_1,Benny_Goodman_Trio_Nice_Work_Avalon 
2015_275_18_1,Feather_On_Jazz_Jazz_In_The_Concert_Hall 
2015_235_1_1,Integration_Report_1 
2015_273_2_1_1,Cab_Calloway_Home_Movie_1 
2015_273_2_2_1,Cab_Calloway_Home_Movie_2 
$ sed -r ':loop;/^[^_]+,/{s/_/ /g;bend};s/_/./;bloop;:end' input.txt 
2015.275.14.1,Siboney by The Tailor Maids 
2015.275.16.1,Louis Armstrong Cant Give You Anything But Love 
2015.275.17.1,Benny Goodman Trio Nice Work Avalon 
2015.275.18.1,Feather On Jazz Jazz In The Concert Hall 
2015.235.1.1,Integration Report 1 
2015.273.2.1.1,Cab Calloway Home Movie 1 
2015.273.2.2.1,Cab Calloway Home Movie 2 

說明:

  1. 使用s/_/./替代_.直到全部已經替換,之前的,這是通過^[^_]+,來判斷的;
  2. 然後,如果^[^_]+,比賽,用s/_/ /g到subtitute所有_,