2013-09-22 65 views
7

我想提取不包含#的行,並在輸出中刪除",;awk:對字符串使用反轉匹配,然後替換字符

我輸入文件看起來像這樣:

# ;string"1" 
# string"2"; 
string"3"; 

可以使用greptr得到想要的輸出:

grep -v '#' FILE | tr -d ';"' 
string3 

不過,我想用awk

我可以提取轉化比賽awk '!/#/' FILE,但我該如何使用sub在同一awk命令刪除";

回答

5

可以使用gsub全球代換系:

awk '!/#/{gsub(/[";]/,"",$0);print}' 

下面的記錄表明這個動作,它提供了與您的grep/tr管線相同的結果:

pax> echo '# ;string"1" 
# string"2"; 
string"3";' | awk '!/#/{gsub(/[";]/,"",$0);print}{}' 

string3 

請注意,最終的{}在某些awk的實現中可能不是必需的,但它在那裏停止輸出不符合所有規則的行的那些實現(通常是較老的)的不匹配行。

+0

+1爲正確的方法。你不需要'gsub()'中的'$ 0' arg,因爲這是默認值。 –

3

使用gsub,而不是將取代所有匹配的不只是一個:

awk '/#/{next}{gsub(/[";]/,"")}1' file 

輸出:

string3 
  • 跳過第三參數gsub使得它在默認情況下處理$0
  • /#/{next}使得它跳過含有#
  • 1使得打印$0
+0

如果你的'測試之前gsub'用於打印哪一行,你不需要'下一個'。看到我的帖子「另一個awk版本」。爲什麼你在'[',;]''內部有''',它不是在請求中被替換掉,所以可以被刪除 – Jotne

+1

@Jotne複雜性仍然是一樣的,甚至更復雜, d一般修改全局分隔符,甚至使用'OFS ='。此外,在排除註釋行之前,您會首先使用gsub進行更多處理,因爲這會處理不再需要的行。這就是我沒有這樣做的原因。謝謝你的方式。我做了更新。 – konsolebox

+0

用於切換爲正邏輯的+1(包含#的跳過行而不是包含#的選擇行),因此如果將來增強腳本,可能會導致腳本不太可能產生雙重負面影響。對此可能有點過分,但試圖讓事情積極的一般概念通常是好的。 OP說'lines CONTAINING#',但不僅僅是以'#'開始的行,所以你可以刪除'^'。 –

2

另一個awk版本

awk -F"[\";]" '{$1=$1} !/^#/' OFS= file 
string3 

awk '{gsub(/[";]/,x)} !/^#/' file 
string3 

x代表什麼。也可以使用了"",但如果你想給sed機會節省一個字符:)

2

sed -n '/^[^#]/s/[";]//gp' file 
string3