我想用include('
替換一組文件中的所有include('./
。我試圖使用awk如下:awk替換單引號
awk '{gsub("include\('"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php
它引發我這個錯誤。
awk: (FILENAME=xyz.php FNR=1) fatal: Unmatched (or \(: /include('.//
任何幫助,將不勝感激。
我想用include('
替換一組文件中的所有include('./
。我試圖使用awk如下:awk替換單引號
awk '{gsub("include\('"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php
它引發我這個錯誤。
awk: (FILENAME=xyz.php FNR=1) fatal: Unmatched (or \(: /include('.//
任何幫助,將不勝感激。
@OP,你可以嘗試使用八進制代碼爲單引號(\047
)和正斜槓(\057
),例如
$ cat file
include('./
$ awk '{gsub(/include\(\047\.\057/ , "include(\047") }1' file
include('
終於有了工作,非常感謝 – GeekTantra 2010-02-25 09:54:38
試試這個:
awk '{gsub("include(\'"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php
你放錯地方的反斜線
或本:
awk '{gsub("include(\'./", "include(\'", $0); print > FILENAME}' *.php
這個怎麼樣?
awk '{gsub("include(\47./", "include(\47", $0); print > FILENAME}' *.php
你有沒有嘗試沒有esacping任何
awk '{gsub("include('./", "include('", $0); print > FILENAME}' *.php
不工作這些錯誤裁剪... awk:警告:轉義序列\'''視爲普通''' awk:warning:轉義序列\'\('視爲普通\'' (' awk:(FILENAME = xyz.php FNR = 1)致命的:無與倫比的(或\(:/include('.// – GeekTantra 2010-02-25 09:33:27
@GeekTantra我沒有控制檯或者安裝了awk,測試以上這些示例.. – ant 2010-02-25 09:40:47
這些都沒有幫助...... – GeekTantra 2010-02-25 09:45:43
此作品(不含I/O重定向的 '打印'):
awk '{gsub(/include\('"'"'.\//, "include\('"'"'", $0); print }' # Wrong
awk '{gsub(/include\('"'"'.\//, "include('"'"'", $0); print }' # Right
它映射此輸入:
include('./abc')
include('x/abc')
發送至:
include('abc')
include('abc')
根據經驗,似乎正則表達式必須在斜線內;替換字符串必須是常規字符串。您需要將'.
'映射到'\.
'以停止第二次替換。
我對這個解釋並不滿意。 MacOS X上'awk'的手冊頁上說:
/re/ is a constant regular expression; any string (constant or variable) may be used as a regular expression, except in the position of an isolated regular expression in a pattern.
因此,理論上,您使用的字符串形式應該工作。經驗上說,它沒有;我得到的代碼與您的代碼基本相同。而且你的shell引用是正確的,這是不平凡的。
有些時候,Perl的可能會更容易(因爲你可以選擇任意分隔符來標記正則表達式邊界):
perl -pe "s%include\('\./%include('%g"
此命令的工作原理,但僅適用於包含一個或兩個類似語句的簡單文件類型...足夠與大量的單引號的大文件,並削減它似乎搞亂了一切。我也得到這個錯誤: awk:warning:轉義序列'\('視爲普通'(' – GeekTantra 2010-02-25 09:49:18
@GeekTantra:這是你需要使用腳本文件的地方:'awk -f file * .php'。那麼就不必與shell的對引號的解釋以及awk對引用的解釋作鬥爭,這使得整個堆棧變得更加容易。注意:MacOS的awk沒有給出,但是括號前的反斜槓替換字符串是不需要的 - 你的'awk'是正確的。 – 2010-02-25 09:57:47
在'gsub'中使用雙引號有它的用途,例如,如果用正斜槓'/'代替,可以用'gsub(「/」,「」)'代替'gsub(/ \ //,「」)' – ghostdog74 2010-02-25 10:23:30
你並不需要使用awk
如果你想要做的就是這個。 :) 此外,在您讀取文件時寫入文件,與您一樣,會導致數據丟失或損壞,儘量不要這樣做。
for file in *.php ; do
# or, to do this to all php files recursively:
# find . -name '*.php' | while read file ; do
# make backup copy; do not overwrite backup if backup already exists
test -f $file.orig || cp -p $file $file.orig
# awk '{... print > NEWFILE}' NEWFILE="$file" "$file.orig"
sed -e "s:include('\./:include(':g" "$file.orig" >"$file"
done
只是爲了澄清數據丟失方面:當awk
(或sed
)開始處理一個文件,你問他們讀的第一線,他們將實際執行緩衝讀取,也就是說,它們將從文件系統中讀取(讓我們簡化並從磁盤中說出)與其內部讀取緩衝區一樣大的數據塊(例如4-65KB),以便獲得更好的性能(通過減少磁盤I/O)。假設你正在使用的文件大於緩衝區大小。進一步的讀取將繼續來自緩衝區,直到緩衝區耗盡,此時第二塊數據將從磁盤裝載到緩衝區等。
但是,剛讀完第一行後第一塊數據從磁盤讀入緩衝區,你的awk
腳本打開FILENAME
,輸入文件本身,用於寫截斷,即磁盤上的文件大小重置爲0。此時,原始文件中剩餘的所有內容都是awk
內存中的前幾個千字節。 Awk
將高興地繼續從內存緩衝區逐行讀取併產生輸出,直到緩衝區耗盡,此時awk
可能會停止併爲您留下4-65k文件。
作爲一個側面說明,如果你實際上是用awk擴展(例如print "PREFIX: " $0
),不縮水(gsub(/.../, "")
),數據,那麼你幾乎肯定會與非響應awk
和永遠成長文件結束。 :)
sed,awk,都可以做這個工作 – ghostdog74 2010-02-28 03:26:25
可以少說引用/轉義級別:)但是真正不可原諒的部分,無論使用哪種(awk或sed),都是埃森在讀取第一行之後,即截斷每個PHP文件,即,如果該文件比awk的/ sed的讀取緩衝區大,他只是將其文件截斷爲同樣多的字節。 – vladr 2010-02-28 04:05:00
awk實際上爲我做了這份工作。它不是關於使用sed或awk關於哪一個更舒適。 – GeekTantra 2010-02-28 04:13:26
是awk某種原因的特定要求?你應該真的使用sed。 'sed -i's/include(\'。\ // include(\'/ g'* .php' – 2010-02-25 09:34:21
sed,awk,都可以做這個工作。 – ghostdog74 2010-02-25 09:55:24
你試過了這裏的doc嗎?那樣你沒有與逃避打擾 – 2010-02-25 09:57:52