2015-09-11 74 views
0

我绑转换匹配的模式,以降低的情况下,我用下面的awk代码,但它是做替换,但也增加了换行符替换后字转换匹配的模式,以较低的情况下,AWK

awk 'BEGIN{ FS = "[&]";RS = ";"; };{ $2 = tolower($2) }{print $0}' test.txt 

测试文件内容:

This is test file & replacing ' PATTERN 

输出我得到的是:

This is test file & 
    replacing ' 
    PATTERN 

回答

0

正如埃德莫顿指出的那样,这是坏了。

你要确保OFSORS是相同的分别为FSRS

当您修改RS时,Awk将更改其的读数行为;但除非您也更改ORS,否则写入行为将保持为默认值,即将换行符作为记录分隔符进行打印。

正如Ed Morton指出的那样,您还需要将FS更改为单个字符&以使您的程序正常工作。但是,通过这个固定的,我得到了预期的产出。

vnix$ awk 'BEGIN{ OFS = FS = "&"; ORS = RS = ";"; };{ $2 = tolower($2) }{print $0}' <<':' 
> This is test file &AMP; replacing &APOS; PATTERN 
> :  
This is test file &amp; replacing &apos; PATTERN 
&; 

一个聪明的解决方案,这已经是95%的荣誉。

+0

不,那将分号添加到末尾从文件末尾剥离换行符,并用'[&]'s替换所有'&'s。不知道为什么OP接受了这个答案。 –

+0

最后我没有看到分号,虽然你说FS'最好改为“&”'。更新答案。感谢您的评论。 – tripleee

+0

你正在设置'ORS =';''然后执行'print $ 0',这样输出不能以分号结束。您发布的输出中缺少输出的“&”部分,它将在下一行的提示符之前出现。 –

1

也许这符合您的需求更好地

awk '{for(i=1;i<=NF;i++) if("&"==substr($i,1,1)) $i=tolower($i)}1' 

转换开始符号的所有单词小写。

或者,如果你想指定第一和最后一个字符的匹配

awk '{for(i=1;i<=NF;i++) if(match($i,"&.*;")) $i=tolower($i)}1' 

˚F

+0

不需要substr()和match(),你可以用'$ i〜/ ^&/'和'$ i〜/ &.*; /'来代替(最后是match()应该真的被锚定'$ i〜/^&.*; $ /')。 –

1

我没有看到一个简单的一行来实现这一目标。或许短脚本:

{ 
    while (match($0, /&[A-Z]+;/)) { 
    tag=substr($0,match($0,/&[A-Z]+;/)+1); tag=substr(tag,0,index(tag,";")); 
    $0=substr($0,0,match($0,/&[A-Z]+;/)) tolower(tag) substr($0,match($0,/&[A-Z]+;/)+length(tag)+1); 
    } 
} 

1 

此步骤通过输入搜索大写标记的每一行,并为每一个发现,代替使用一组功能substr()线。

测试:

$ echo "This is test file &AMP; replacing &APOS; PATTERN" | gawk -f ~/doit.awk 
This is test file &amp; replacing &apos; PATTERN 

您可以在上面放一个“认领”,如果你希望能够将此独立运行。它可以在gawk或BSD awk中工作,所以它应该在大多数操作系统中都很开心。

+0

它在任何awk中的行为都是一样的。唯一的可移植性问题是在'[A-Z]'不代表'大写字母'的语言环境中,您应该使用'[[:upper:]]'代替。 –

0

这是真的sed的工作:

$ sed -r 's/&[^;]+/\L&/g' file 
This is test file &amp; replacing &apos; PATTERN 

如果它是便携式的awk那么它会是:

$ awk '{rec=""; while(match($0,/&[^;]+/)) { rec = rec substr($0,1,RSTART-1) tolower(substr($0,RSTART,RLENGTH)); $0=substr($0,RSTART+RLENGTH)} print rec $0}' file 
This is test file &amp; replacing &apos; PATTERN 
+0

不幸的是,'-r'和'\ L'都不是可移植的,尽管这应该适用于现代Linux'sed'。 – tripleee

+0

好的,我添加了便携式awk等价物。 –