2012-05-23 31 views
2

我喜歡awk的是,您可以從文件中獲取滿足您指定的某個任意字段上的條件的所有行。 例如,如何在您指定的某個任意字段上執行regex替換

awk '$3~/hi/' < test.txt # print all lines where the third field matches the pattern "hi" 

awk '$2>=2' < test.txt # print all lines where the second field is greater or equal to 2 

至於誰是學習UNIX的強大初學者,我絕對着迷此。 現在我想知道是否有一種簡單的方法來執行正則表達式替換隻在您指定的一些任意字段?例如,我只想在第三個字段上進行regex替換。 我目前的方法是「剪切」我想要的字段並使用perl或sed執行替換,然後將其「粘貼」到原始文件。但我想知道是否有更有效的方法來實現這一點。

感謝

回答

4

既然你標有「perl的」這個問題(除了「sed的」,「AWK」,「UNIX」和「命令行」),我會假設你有興趣在包含任何上述工具的答案中。

Perl有自動分割命令行開關(-a):

perl -lane 'print if $F[2] =~ /some pattern/' filename 

...或...

perl -lane 'print if $F[1] >= 42' filename 

-a導致自動分割成@F陣列。 -n會導致Perl遍歷您提供的文件的行。剩下的就是編程。 )

現在對於取代:

perl -i.bak -lane '$F[2] =~ s/match/subst/; print join q/ /, @F' filename 

或者,使用-p開關,它告訴Perl因爲它出現在$_打印每行短一些。這意味着如果你改變@F,你必須回到其複製到$_

perl -i.bak -pale '$F[2] =~ s/match/subst/ && $_="@F"' filename 
3

這可能會爲你工作:

echo -e 'Fred barney Wilma\nfoo bar baz' | 
awk '$2 == "barney"{sub(/b/,"B",$2)};1' 
Fred Barney Wilma 
foo bar baz 

可以使用subgsub命令或此這種情況下, :

echo -e 'Fred barney Wilma\nfoo bar baz'| 
awk '$2 == "barney"{$2="Barney"};1' 
Fred Barney Wilma 
foo bar baz 

只是完全替換第二個字段。

N.B.該行末尾的1{print}的簡寫。

1

考慮一個簡單的例子:

awk -F "," '{ OFS=","; sub ("1", "x", $3); print $0 }' file.txt > newfile.txt

newfile.txt現在將包含:

1,2,3,4,5,6,7 
8,9,x0,11,12,13,14 
15,16,x7,18,19,20,21 

這裏,1在第三列$3x代替。
-F ","設置輸入文件的分隔符。 OFS=","向輸出添加逗號。

如果您想在全球範圍內進行替換,請考慮使用gsub而不是sub

HTH

+1

我認爲這將是更好的一次讀取輸入文件中的'BEGIN'塊,像'AWK -F之前設置'OFS'值 「」「BEGIN {OFS = 「」 } {sub ...}'' – Birei

相關問題