如何在AWK中用括号括起所有空格填充的单词?

时间:2014-05-11 01:47:54

标签: regex bash awk

我有一个这样的文件:

all <div class="first">these</div> <div class="second">words</div> <div class="second">are</div> <div class="second">marked</div> <div class="second">but</div> these words are not.
<div class="first">this</div> is <div class="second">another</div> <div class="second">example</div> with <div class="second">some</div> unmarked words.

我需要在前后有空格的所有单词周围放置大括号,例如输出为:

all <div class="first">these</div> <div class="second">words</div> <div class="second">are</div> <div class="second">marked</div> <div class="second">but</div> {these} {words} {are} not.
<div class="first">this</div> {is} <div class="second">another</div> <div class="second">example</div> {with} <div class="second">some</div> {unmarked} words.
  • all没有给大括号,因为之前没有空格。
  • not.words.未被替换,因为之后没有空格。

我用awk尝试过许多不同的东西,但没有什么能正常运作。这是我能得到的最接近的:

awk '{ gsub(/.[[:blank:]][[:alpha:]][[:blank:]]*/, "{&}"); }1'
  • 字词只能包含以下字母:abcdef,{{1} },ghijklmnopqrstuv,{{ 1}},wxy以及大写等值。
  • 字词不能包含上面未列出的任何其他符号。例如,如果zü1出现在两个空格中的某个位置,则不会将其视为匹配。

4 个答案:

答案 0 :(得分:5)

除非您有其他方法可以执行此操作,否则您需要使用awk或{{1}不支持的 lookahead lookbehind 断言}}。使用Perl,您可以执行以下操作。

sed

答案 1 :(得分:4)

使用GNU sed,您可以创建一个循环并在单词周围添加大括号。

$ sed -r ':a;s/ ([[:alpha:]]+) / {\1} /;ta' file
all <div class="first">these</div> <div class="second">words</div> <div class="second">are</div> <div class="second">marked</div> <div class="second">but</div> {these} {words} {are} not.
<div class="first">this</div> {is} <div class="second">another</div> <div class="second">example</div> {with} <div class="second">some</div> {unmarked} words.

可以修改角色类以满足您的要求。

答案 2 :(得分:3)

awk脚本适用于示例数据:

awk '{ for (i = 1; i <= NF; i++)
         if ($i ~ /^[[:alpha:]]+$/ && (i != 1 || $0 ~ /^ /))
            $i = "{" $i "}"
       print $0
     }' data

对于给定的输入,输出正是所需的输出。条件要求每个字段中的单词都是字母,并且“不是第一个单词,或者整个行是否以空白开头”。如果最后有一个全字母字词,您可以在&& (i != NF || $0 ~ / $/)语句中添加条件if

我根据问题使用了[[:alpha:]],假设在您的语言环境中,ü作为字母字符有效。如果您只需要简单的拉丁字母加ü(U + 00FC,LATIN SMALL LETTER U WITH DIAERESIS)和Ü(U + 00DC,LATIN CAPITAL LETTER U WITH DIAERESIS),那么您可以替换该字符改为使用[a-zA-ZüÜ]的课程。只有使用a-zA-Z才能搞砸EBCDIC,你知道这对你来说是否有问题。您可以根据需要进行修改,以获得您感兴趣的角色。

答案 3 :(得分:3)

使用gensub()\s的GNU awk:

awk '{while((new=gensub(/(\s)([[:alpha:]]+)(\s)/,"\\1{\\2}\\3","g")) != $0) $0=new}1' file