用Awk替换并保留FS至OFS

用Awk替换并保留FS至OFS,awk,fs,Awk,Fs,我有一个下面有输入文本的文件(这不是原始文件,只是输入文本的示例),我想将所有2个字母的字符串替换为数字100。在这个文件中,FS可以是:、|或“”(空格),我别无选择,只能将它们全部视为FS,我希望将这些字段分隔符保留在输出中的原始位置(如在输入文件中) 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

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

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
awk -F '[[:blank:]:|]+' '
   {
   split( $0, 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
不需要字段分隔在这种情况下,将所有大写字母组更改为“100”,除非您在OP中指定了其他约束(与字符串中的其他元素一样,您需要指定可能的内容,理想情况下,将预期结果的示例添加为univoq)

现在你肯定有更多的事情要做,所以这段代码肯定会失败,因为它将像
ABC:DEF
这样的东西更改为
100C:100F
,这当然是不可能的

在这种情况下

sed 's/[A-Z]\{2\}/100/g' YourFile
awk '{gsub(/[A-Z]{2}/, "100"); print}' YourFile
awk -F '[[:blank:]:|]+' '
   {
   split( $0, 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
awk-F'[:blank:::|]+'
{
拆分($0,aS,/[^[:blank:::|]+/)
对于(i=1;在这种情况下i)

sed 's/[A-Z]\{2\}/100/g' YourFile
awk '{gsub(/[A-Z]{2}/, "100"); print}' YourFile
awk -F '[[:blank:]:|]+' '
   {
   split( $0, 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
不需要字段分隔在这种情况下,将所有大写字母组更改为“100”,除非您在OP中指定了其他约束(与字符串中的其他元素一样,您需要指定可能的内容,理想情况下,将预期结果的示例添加为univoq)

现在你肯定有更多的事情要做,所以这段代码肯定会失败,因为它将像
ABC:DEF
这样的东西更改为
100C:100F
,这当然是不可能的

在这种情况下

sed 's/[A-Z]\{2\}/100/g' YourFile
awk '{gsub(/[A-Z]{2}/, "100"); print}' YourFile
awk -F '[[:blank:]:|]+' '
   {
   split( $0, 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
awk-F'[:blank:::|]+'
{
拆分($0,aS,/[^[:blank:::|]+/)

对于(i=1;i请尝试此sed一行:

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


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

尝试一下这个sed一行:

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


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

POSIX awk中没有保留与RS(POSIX)定义的字符串相匹配的字符串的功能因为在POSIX中RS仅仅是一个字符串,所以不需要这样的功能,并且为每个FS匹配的字符串执行这样的功能将是不必要的低效,因为它很少需要

在GNU awk中,RS可以是一个regexp,而不仅仅是一个字符串,您可以保留与regexp RS和RT匹配的字符串,但是没有任何功能可以保留与FS匹配的值,因为POSIX没有这样做。相反,在GNU awk中,他们为split()添加了第四个参数因此,如果需要,您可以自己在数组中保留与FS匹配的字符串(
seps[]
如下):

$awk-vfs='[:|]'{
拆分($0,FLD,FS,SEP)
gsub(/[A-Z]{2}/,“100”)

对于(i=1;i,POSIX awk中没有保留与RS(POSIX)或FS定义的regexp相匹配的字符串的功能。由于POSIX RS中的RS只是一个字符串,因此不需要这样的功能,并且为每个FS匹配的字符串执行此操作将不必要地低效,因为它很少需要

在GNU awk中,RS可以是一个regexp,而不仅仅是一个字符串,您可以保留与regexp RS和RT匹配的字符串,但是没有任何功能可以保留与FS匹配的值,因为POSIX没有这样做。相反,在GNU awk中,他们为split()添加了第四个参数因此,如果需要,您可以自己在数组中保留与FS匹配的字符串(
seps[]
如下):

$awk-vfs='[:|]'{
拆分($0,FLD,FS,SEP)
gsub(/[A-Z]{2}/,“100”)

对于(i=1;i您的代码似乎与我的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]/
您的代码似乎与我的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]/

使用sed而不是awk。您可以为给定的输入更新样本输出吗?什么不起作用?我已经更新了所需的输出。使用sed而不是awk。您可以为给定的输入更新样本输出吗?什么不起作用?我已经更新了所需的输出。gnu sed看到
-r
并且
没有转义()|
.Change-mayby``by
[:blank:][/code>和递归(2次似乎足够)release,以便在final
sed-r/(^ |[:blank:][A-Z][A-Z][A-Z]([:;[:blank:][blank:][A-Z])/\1100\2/g;s/\1100\2/g'您的文件
gnu-sed看到了
-r
,无法逃脱
[:blank:][/code>和递归(2次似乎足够)relation,用于两个字母的对应组,因此在final
sed-r/(^ |[:|[:blank:][A-Z]([:[blank:][A-Z:][A-Z:$)/\1100\2/g;s/\1100\2/g'您的文件中
我认为您给出的awk解决方案和我的命令awk-F“[::|]”{gsub A-Z],“{100}”之间没有任何区别;print}'我只是想弄清楚我的命令有什么问题。有一个问题,你的字段分隔符设置不同。我不认为你给出的awk解决方案和我的命令awk-F“[:|]”{gsub(/[A-Z]{2}/,“100”);print}之间有任何区别'我只是想弄清楚我的命令有什么问题。有一个问题,你的字段分隔符被设置为不同的答案等级,但是当我执行它时,我得到这个awk:fatal:4作为split的参数数是无效的,我想我的awk版本(GNU awk 3.1.5)不支持4个要拆分的参数。您知道哪个awk基本版本支持4个要拆分的参数吗?我认为[A-Z]{2}类型语法也不受3.1.5支持。不客气。正确,您使用的是gawk的过时版本。第4个要拆分的参数()从版本4.0 whic开始出现