2011-07-08 127 views
5

我想要更改文件中每一行的格式,並且還要在其中一個匹配的組上運行另一個替換。有沒有辦法嵌套sed替換?

作爲一個例子,我可以有一個簡單的三列CSV文件(沒有轉義),我想以另一種格式。

sed -r 's/^([a-z]+),([a-z]+),([a-z]+)$/\1: \3 (\2)' 
# would turn "comma,separated,values" 
# into  "comma: values (separated)" 

不過,我也希望從第二列中刪除所有的元音,即在\2運行s/[aeiou]//g

是否有一個很好的解決方案來解決這個嵌套替換問題?請假設這兩個替換都很複雜,而這僅僅是一個例子。

我的sed不是GNU sed 4.0版本。

+0

你不能將一個sed管入第二個? – NorthGuard

+0

@inTide:我不想刪除_all_元音,只是那些來自第二列的元音。 – Tim

+0

對,所以第一個sed你刪除逗號和第二個sed之間的所有元音,你首先用逗號':'和第二個逗號'()'。 – NorthGuard

回答

0

我覺得你最好用awk這個,這樣可以更容易操縱這些字段。

echo "gaviidae,gruidae,picidae" | awk -F "," '{gsub(/[aeiou]/, "", $2); printf("%s: %s (%s)\n", $1, $3, $2)}' 

輸出:

gaviidae: picidae (grd) 
+0

我不知道'awk';有沒有一種簡單的方法來匹配'sed'類似的方式?你的命令似乎分裂在'',',所以它不是很一般。 – Tim

+0

字段分隔符由-F參數設置。它接受正則表達式,但不以您使用反向引用編寫它們的方式。如果你的格式需要更復雜的解析來分割字段,我會授予awk不是很有幫助。 – Simon

1

這是神祕的(像幾乎所有的非平凡SED),但它會做的工作。它利用了你希望修改過的單詞在最後走的事實 - 如果你想讓它進入其他位置,同樣的技巧將會起作用,但命令會稍微長一些。

sed 'h;s/.*,([a-z]+),.*/(\1)/;s/[aeiou]//g;x;s/([a-z]+),[a-z]+,([a-z]+)/\1: \2 /;G;s/\n//' 

或英文:「保存在保持緩衝副本,殺死所有,但第二個字,去掉元音,交換緩衝區,重新排列的話(他們去掉了中間的一個),添加其他緩衝區到最後,刪除新行「。

相關問題