用 awk 替换并保留 FS 到 OFS

Replacing with Awk and preserving the FS to OFS

我有一个文件,下面有输入文本(这不是原始文件,只是输入文本的示例),我想将所有 2 个字母的字符串替换为数字 100。在这个文件中 FS 可以是 :,|或 " " (space) ,我别无选择,只能将它们全部视为 FS,并且我想将这些字段分隔符保留在输出 [=13 中的原始位置(如输入文件中) =]

A:B C|D
AA:C EE G
BB|FF XX1 H
DD:MM:YY K

我试过了

awk  -F"[:| ]"  '{gsub(/[A-Z]{2}/,"100");print}'

但这好像不行,请指点。

期望的输出:

A:B C|D
100:C 1000 G
100|100 1001 H
100:100:100 K

在这种情况下

sed 's/[A-Z]\{2\}/100/g' YourFile
awk '{gsub(/[A-Z]{2}/, "100"); print}' YourFile

在这种情况下不需要字段分隔,将所有大写字母组更改为“100”,除非您在 OP 中指定其他约束(就像字符串中的其他元素一样,您需要指定可能的内容和理想情况下,将预期结果的样本添加为 univoq)

现在你肯定有更多的东西了,所以这段代码肯定会失败,因为把 ABC:DEF100C:100F 之类的东西改成肯定不是预期的

在这种情况下

awk -F '[[:blank:]:|]+' '
   {
   split( [=11=], aS, /[^[:blank:]:|]+/)
   for( i=1;i<=NF;i++){
      if( $i ~ /^[A-Z][A-Z]$/) $i = "100"
      printf( "%s%s", $i, aS[i+1])
      }
   printf( "\n" )
   } ' YourFile

试试这个 sed one-liner:

kent$  sed -r 's/(^|[:| ])[A-Z][A-Z]([:| ]|$)/00/g' file  
A:B C|D
100:C 100 G
100|FF XX1 H
100:MM:100 K

注:

这将搜索和替换模式:两个分隔符 之间的确切两个 [A-Z]。如果这不是您想要的,请粘贴所需的输出。

POSIX awk 没有保留与 RS (POSIX) 定义的字符串或 FS 定义的正则表达式相匹配的字符串的功能。由于在 POSIX 中 RS 只是一个字符串,因此不需要这样的功能,并且由于很少需要,所以对每个 FS 匹配字符串执行此操作将不必要地低效。

使用 GNU awk,其中 RS 可以是正则表达式,而不仅仅是字符串,您可以保留与正则表达式 RS 与 RT 匹配的字符串,但没有功能可以保留与 FS 匹配的值,原因与POSIX 不这样做。相反,在 GNU awk 中,他们向 split() 添加了第 4 个参数,因此如果需要,您可以自己在数组中保留与 FS 匹配的字符串(seps[] 下面):

$ awk -v FS='[:| ]' '{
    split([=10=],flds,FS,seps)
    gsub(/[A-Z]{2}/,"100")
    for (i=1;i<=NF;i++) {
        printf "%s%s", $i, seps[i]
    }
    print ""
}' file
A:B C|D
100:C 100 G
100|100 1001 H
100:100:100 K

the GNU awk manual 中查找 split() 了解更多信息。

你的代码似乎在我的 Gnu awk 上工作得很好:

A:B C|D
100:C 100 G     # even the typo in this record got fixed.
100|100 1001 H
100:100:100 K

我会说问题是正则表达式 /[A-Z]{2}/ 应该写成 /[A-Z][A-Z]/.