awk替换单引号
我想用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