2016-09-15 14 views
1

我可以刪除特定格式的文本並縮短​​或更長的文本sed '/^.\{25\}..*/d' -i FILE,但如何合併在sed模式和長度?如何刪除某個文件中符合特定格式並長於或短於特定長度的文件中的行

含有A系應該是包含B應該是包含C應該是所有其他線3和字符

之間8

線10和15個字符

之間

線20和字符之間25

應從文件中刪除

1234567890 A 1234567890 
12345 A 12345 
1 A 1 
1234567890 B 1234567890 
12345 B 12345 
1 B 1 
1234567890 C 1234567890 
12345 C 12345 
1 C 1 

從而使輸出應該是這樣的

1234567890 A 1234567890 
12345 B 12345 
1 C 1 

回答

2

這是你如何與sed的做到這一點:

$ sed -ne '/A/ s/^\(.\{20,25\}\)$/\1/p; /B/ s/^\(.\{10,15\}\)$/\1/p; /C/ s/^\(.\{3,8\}\)$/\1/p;' file 
1234567890 A 1234567890 
12345 B 12345 
1 C 1 

它是如何工作:

-ne - suppress printing pattern 
/A/ - look for pattern A 
^\(.\{20,25\}\)$ - line with 20-25 characters 
/\1/p - print pattern space 
0

下面是一個awk解決方案

awk '/.*A.*/ && length($0) > 19 && length($0) < 26 \ 
|| /.*B.*/ && length($0) > 9 && length($0) < 16 \ 
|| /.*C.*/ && length($0) > 2 && length($0) < 9' test1.dat 

編輯

這裏還有更高效的版本,在這裏我們只得到了length($0)一次

awk '{len=length($0)} 
/.*A.*/ && len > 19 && len < 26 \ 
|| /.*B.*/ && len > 9 && len < 16 \ 
|| /.*C.*/ && len > 2 && len < 9' test1.dat 

輸出

1234567890 A 1234567890 
12345 B 12345 
1 C 1 

我已經遞增/遞減的邊界號碼逐個消除需要與<=>=(這是更昂貴的測試,以測試。在一個非常大的文件上它可能花費你30秒(只是猜測!))。

(不要讓任何空格字符在\後面的這些續行結尾處)蠕變。

(此外,您可以刪除該\字符,並將其摺疊爲單行,如果您需要的話。)


這可以增強接受變量值,我包括一個簡短的例子在這裏,整理出來你的需求可以被看作是一個機會,學習;-)

awk -v lim1=10 -v lim2=26 '/.*A.*/ && length($0) > lim1 && length($0) < lim2 ... 

IHTH

+0

考慮使用一個變量,而不是每行調用'length()'最多6次,所有的'*'都不做任何事情。 –

+1

@EdMorton:好主意。但是,除非我知道O.P.是否可以使用'awk'解決方案,否則不想花費更多時間。此外,這將需要使用「{if(...)....}」的查看形式。是不是模式/動作形式的首選; - >?我明天會爲你的想法添加一個編輯。祝你們好運。 – shellter

+1

這只是對{n = length()}/A /&&n> 19 && n <26 ||的調整。 ....'。 –

1

用AWK,你可以簡單地寫條件的布爾表達式,你不是卡住試圖讓出了正則表達式的條件:

$ awk '(/A/ && /^.{20,25}$/) || (/B/ && /^.{10,15}$/) || (/C/ && /^.{3,8}$/)' file 
1234567890 A 1234567890 
12345 B 12345 
1 C 1 
相關問題