2014-09-19 59 views
3

鑑於這種簡單的sed命令:如何在perl sed-like find/replace命令中跳過不匹配?

echo "abc\nxyz" | sed "s/abc/***/" 

等效Perl版本是

echo "abc\nxyz" | perl -pe "s/abc/***/" 

桑達讓我只輸出匹配的行這樣的:

echo "abc\nxyz" | sed -n "s/abc/***/p" 

如何做到這一點與Perl的?我想使用Perl的正則表達式引擎,它比sed更加全面,但是我想要這個sed選項。

+1

嘗試['super-sed'](https://directory.fsf.org/wiki/Super-sed)。 'sed'從外面看,'perl'從裏面看! – 2014-09-19 20:17:52

回答

1

在Perl -p開關設置了一個隱含的循環,在輸入迭代,並打印的$_循環的每次迭代後的內容。 Perl中也有-n開關需要,這隱含的循環內的代碼處理其自己的輸出:

echo "abc\nxyz" | perl -ne 's/abc/***/ && print'

-p-n開關在perlrun說明。

總之,-p形成一個隱含的循環,看起來是這樣的:

while(<>) { 
    # Your code goes here... 
} 
continue { 
    print; 
} 

而且-n形成一個隱含的循環,看起來是這樣的:

while(<>) { 
    # Your code goes here.... 
} 

因此,與-n,你必須明確指定何時產生輸出,以及該輸出應該是什麼。通過重新獲得對輸出的控制,您可以合併允許「打印」僅在符合某些條件(例如正則表達式匹配)時發生的邏輯。在我的例子中,如果匹配成功,我們使用邏輯短路來觸發打印。

+0

完美!謝謝! – clay 2014-09-19 20:20:23

+0

這是'perl -p'的一種很差的表示形式,它可以逐行讀取輸入文件,並且可以打印它們,無論它們是否被代碼修改。 *「打印每個發生的轉化的結果」*是錯誤的。 – Borodin 2014-09-19 20:39:49

+0

@Borodin澄清了前兩句話。 – DavidO 2014-09-19 20:50:04

3

Perl的-p選項意味着在輸入的每一行上執行-e ...的操作,然後打印。更改爲-n表示讀取文件的每一行,然後分別執行-e ...。所以,你要啥子實現的一個簡單的方法如下:

echo "abc\nxyz" | perl -ne "print if s/abc/***/" 
+0

謝謝!這個答案也可以,但我只能接受一個。 – clay 2014-09-19 20:20:40