我想用include('./
替换一组文件中的所有include('
。我试图使用awk如下:
awk '{gsub("include\('"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php
它抛出了这个错误。
awk: (FILENAME=xyz.php FNR=1) fatal: Unmatched ( or \(: /include('.//
任何帮助都将不胜感激。
答案 0 :(得分:12)
@OP,你可以尝试使用八进制代码作为单引号(\047
)和正斜杠(\057
),例如
$ cat file
include('./
$ awk '{gsub(/include\(\047\.\057/ , "include(\047" ) }1' file
include('
答案 1 :(得分:2)
这有效(没有“打印”上的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 /是一个常数正则表达式;任何字符串(常量或变量)都可以用作正则表达式,但模式中孤立正则表达式的位置除外。
因此,理论上,您使用的字符串形式应该有效。根据经验,它没有;我得到的代码与您的代码完全相同。而且你的shell引用是正确的,这是非常重要的。
有时Perl可能更容易(因为您可以选择任意分隔符来标记正则表达式边界):
perl -pe "s%include\('\./%include('%g"
答案 2 :(得分:0)
试试这个:
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
你有没有尝试过任何事情
awk '{gsub("include('./", "include('", $0); print > FILENAME}' *.php
答案 3 :(得分:0)
如果你想要做的就是这个,你不需要使用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
,输入文件本身用于写入< strong> with truncation ,即磁盘上文件的大小重置为0 。此时,原始文件的剩余部分是awk
内存中前几千字节的数据。 Awk
将快速继续从内存缓冲区中逐行读取并生成输出,直到缓冲区耗尽,此时awk
可能会停止并留下4-65k文件。< / p>
作为旁注,如果你实际上使用awk进行扩展(例如print "PREFIX: " $0
),而不是缩小(gsub(/.../, "")
)数据,那么你几乎肯定会得到一个无响应awk
和永久增长的文件。 :)