awk替换单引号

问题描述:

我想用include('替换一组文件中的所有include('./。我试图使用awk如下:awk替换单引号

awk '{gsub("include\('"'"'./", "include\('"'"'", $0); print > FILENAME}' *.php 

它引发我这个错误。

awk: (FILENAME=xyz.php FNR=1) fatal: Unmatched (or \(: /include('.// 

任何帮助,将不胜感激。

+1

是awk某种原因的特定要求?你应该真的使用sed。 'sed -i's/include(\'。\ // include(\'/ g'* .php' – 2010-02-25 09:34:21

+1

sed,awk,都可以做这个工作。 – ghostdog74 2010-02-25 09:55:24

+0

你试过了这里的doc吗?那样你没有与逃避打扰 – 2010-02-25 09:57:52

@OP,你可以尝试使用八进制代码为单引号(\047)和正斜杠(\057),例如

$ cat file 
include('./ 
$ awk '{gsub(/include\(\047\.\057/ , "include(\047") }1' file 
include(' 
+0

终于有了工作,非常感谢 – 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 
+0

不工作这些错误裁剪... awk:警告:转义序列\'''视为普通''' awk:warning:转义序列\'\('视为普通\'' (' awk:(FILENAME = xyz.php FNR = 1)致命的:无与伦比的(或\(:/include('.// – GeekTantra 2010-02-25 09:33:27

+0

@GeekTantra我没有控制台或者安装了awk,测试以上这些示例.. – ant 2010-02-25 09:40:47

+0

这些都没有帮助...... – 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" 
+0

此命令的工作原理,但仅适用于包含一个或两个类似语句的简单文件类型...足够与大量的单引号的大文件,并削减它似乎搞乱了一切。我也得到这个错误: awk:warning:转义序列'\('视为普通'(' – GeekTantra 2010-02-25 09:49:18

+0

@GeekTantra:这是你需要使用脚本文件的地方:'awk -f file * .php'。那么就不必与shell的对引号的解释以及awk对引用的解释作斗争,这使得整个堆栈变得更加容易。注意:MacOS的awk没有给出,但是括号前的反斜杠替换字符串是不需要的 - 你的'awk'是正确的。 – 2010-02-25 09:57:47

+0

在'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和永远成长文件结束。 :)

+0

sed,awk,都可以做这个工作 – ghostdog74 2010-02-28 03:26:25

+0

可以少说引用/转义级别:)但是真正不可原谅的部分,无论使用哪种(awk或sed),都是埃森在读取第一行之后,即截断每个PHP文件,即,如果该文件比awk的/ sed的读取缓冲区大,他只是将其文件截断为同样多的字节。 – vladr 2010-02-28 04:05:00

+0

awk实际上为我做了这份工作。它不是关于使用sed或awk关于哪一个更舒适。 – GeekTantra 2010-02-28 04:13:26