2012-03-12 98 views
14

我試圖用命令行perl替換多行文件中的文本。我正在使用Ubuntu Natty。Perl命令行多行替換

下面是我的文本文件(稱爲的test.txt)的內容:

[mysqld] 
# 
# * Basic Settings 
# 

# 
# * IMPORTANT 
# If you make changes to these settings and your system uses apparmor, you may 
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld. 
# 

user   = mysql 
socket   = /var/run/mysqld/mysqld.sock 
port   = 3306 
basedir   = /usr 
datadir   = /var/lib/mysql 
tmpdir   = /tmp 
skip-external-locking 

下面是我的Perl命令:

perl -i -pe "s/(\[mysqld\][^\^]+)/\1\nsometext/g" test.txt 

然而,而不是替換文件中的所有文本下面就是我結束了:

[mysqld] 

sometext# 
# * Basic Settings 
# 

# 
# * IMPORTANT 
# If you make changes to these settings and your system uses apparmor, you may 
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld. 
# 

user   = mysql 
socket   = /var/run/mysqld/mysqld.sock 
port   = 3306 
basedir   = /usr 
datadir   = /var/lib/mysql 
tmpdir   = /tmp 
skip-external-locking 
# 

我試過正則表達式中使用RegexBuddy的Perl和與之相匹配es文本文件中的所有內容,但由於某些原因,它在命令行上不能使用perl。

我希望得到一些幫助。

在此先感謝。

+5

我不確定預期的結果應該是什麼。 – cornuz 2012-03-12 16:21:33

+0

@cornuz我認爲這個問題很明顯。我說:「不是替換文件中的所有文本,[以下]就是我最終的結果......」這樣就可以很好地解釋它。同樣來自正則表達式,我認爲這似乎很清楚我需要什麼結果。 – 2012-03-12 18:02:24

回答

24

您正在逐行讀取文件,因此只有第一行符合您的正則表達式。您想要做什麼 - 如果您真的希望刪除大部分內容 - 就是通過使用-0選項來吸引文件。 -0777。這是行結束處理,並且777只是一個常規使用的數字,它足夠大以致導致文件混淆。

perl -0777 -i -pe 's/(\[mysqld\][^\^]+)/$1\nsometext/g' test.txt 

此外,我替換了您的報價。如果你在* nix,看起來你是,單引號是更可取的。例如,$1不會被shell插入。

+0

非常感謝。我必須將其修改爲:'perl -0777 -i -pe「s /(\ [mysqld \] [^ \ ^] +)/ \ 1 \ nsometext/g」test.txt「,因爲我打算需要稍後使用一些shell變量。乾杯。 – 2012-03-12 18:17:13

+0

@ChuckUgwuh很高興幫助。 – TLP 2012-03-12 18:18:32

+0

乾杯。你知道我可以如何使用單引號包含shell變量?!在雙引號中,我會這樣做:'perl -0777 -i -pe「s /(\ [mysqld \] [^ \ ^] +)/ \ 1 \ n $ var/g」test.txt「很高興知道如何使用單引號實現相同的功能?!再次感謝。 – 2012-03-12 20:25:35

5

-p switch導致Perl遍歷輸入的每個,併爲每個輸入執行給定的代碼(以及之後打印行)。具體而言,該命令

perl -p -e 'SOME_CODE_HERE;' 

完全等同於運行下面的Perl程序:

LINE: while (<>) { 
    SOME_CODE_HERE; 
} continue { 
    print or die "-p destination: $!\n"; 
} 

你的正則表達式似乎打算一旦在匹配多行,這顯然是行不通的,如果Perl是逐行處理輸入。爲了使工作打算,你有(至少)兩個選項:何謂使用-0NNN switch

  1. 變化Perl的概念。特別是,開關-0777導致Perl將每個輸入文件視爲單個「行」。

  2. 將代碼重寫爲例如使用.. flip-flop operator

順便說一句,我強烈懷疑你的正則表達式並不意味着你的想法。特別是,[^\^]+匹配不包含插入符號(^)的一個或多個字符的字符串。由於您的輸入似乎不包含任何插入符號,因此這似乎基本上等同於(?s:.+)(或者如果您使用/s modifier,則只是.+)。

+0

謝謝。根據你的回答,我並不完全熟悉命令行,但我覺得它很有教育意義。乾杯 – 2012-03-13 00:34:22