2012-10-15 79 views
5

我想將匹配結果的特定部分存儲爲稍後用於替換的變量。我希望將它保留在一行中,而不是在事先找到我需要的變量。配置Apache的時候,和使用mod_rewrite,你可以specificy的模式特定部分在sed命令中使用佔位符/變量

用作變量,像這樣:

RewriteRule ^www.example.com/page/(.*)$ http://www.example.com/page.php?page=$1 [R=301,L] 

多數民衆贊成包含在括號內的模式匹配的部分存儲用$ 1供以後使用。所以如果網址是www.example.com/page/home,它將被替換爲www.example.com/page.php?page=home。所以比賽的「主場」部分被保存在$ 1中,因爲它是括號內模式的一部分。

我想要這樣的功能與sed命令,我需要自動替換SQL轉儲文件中的許多字符串,以添加刪除表,如果在每個創建表之前存在的命令,但我需要知道表名稱做這一點,所以如果轉儲文件包含類似:

... 
CREATE TABLE `orders` 
... 

我需要運行類似:

cat dump.sql | sed "s/CREATE TABLE `(.*)`/DROP TABLE IF EXISTS $1\N CREATE TABLE `$1`/g" 

得到的結果是:

... 
DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

我在sed命令中使用mod_rewrite語法作爲我試圖做的一個邏輯例子。

有什麼建議嗎?

回答

8
sed '/CREATE TABLE \([^ ]*\)/ s//DROP TABLE IF EXISTS \1; &/' 

查找CREATE TABLE語句並捕獲表名。將它替換爲'DROP TABLE IF EXISTS'和表名,再加上一個分號來終止語句,以及匹配的副本以保留CREATE TABLE語句。

這是經典的sed表示法。由於您使用的是bash,因此您有可能使用GNU sed,並且需要添加--posix才能使用該表示法,否則您需要使用腳本來使用GNU的非標準sed正則表達式。我也沒有試圖在輸出中插入換行符。如果GNU sed對您來說足夠重要,您可以使用GNU sed

關鍵是圓括號(通常需要用反斜線轉義)是捕獲機制,而反斜槓數是替代機制。

+0

感謝您對此的解釋,它已經完全回答我的問題。 –

6
sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" dump.sql 

測試

kent$ cat t.txt 

CREATE TABLE `orders` 
... 

CREATE TABLE `foo` 
... 
... 

CREATE TABLE `bar` 
... 


kent$ sed -r "s/CREATE TABLE (\`.*\`)/DROP TABLE IF EXISTS \1\n &/g" t.txt 

DROP TABLE IF EXISTS `orders` 
CREATE TABLE `orders` 
... 

DROP TABLE IF EXISTS `foo` 
CREATE TABLE `foo` 
... 
... 

DROP TABLE IF EXISTS `bar` 
CREATE TABLE `bar` 
... 
+0

謝謝,這是一個很好的例子。 –