仅当字符串“NA”位于文件的第 6 个字段中时,我才需要将其编辑为“Na”。我目前可以使用以下方法实现此目的:
awk '{gsub("NA","Na",$6)}1' $filename
但是我需要一个附加条件,即如果字符串“HEM”在同一行,则不会发生这种情况。例如,我希望以下行保持不变:
7353 NA 5.4433 24.4404 -3.0784 NA 456 HEM
最后,上述命令删除了字段之间的额外填充。如果有一个命令可以在不改变字段间距的情况下实现这一点,那就太棒了,但这个功能不是必需的。
我认为这可以通过花一些时间读取每个文件并打印每一行,然后只用 if 语句进行编辑来完成,但我试图避免这种笨重的事情。
我觉得这个任务很难用简单的方式完成,但如果有 unix 专家知道如何做,我将不胜感激。谢谢!
使用 GNU awk 将第三个参数改为
match()
and\s
/\S
简写:或者使用任何 POSIX awk:
使用
gawk
:——摘自AWK 编程语言
或者
用
perl
代替awk
:^\s*(\S+\s+){5}\K\S+
匹配s
开头的可选空格,后跟5
非空格S
+s
空格,再后跟非空格(第6 个字段),我们K
将其视为匹配项。$& =~ s/NA/Na/gr
被评估为 perl 代码,其中匹配的 ( )中的 ubstitutione
的结果s
(g
全局类似于您的gsub()
)被返回作为外部的替换。NA
Na
$&
r
s{regex}{replacement}e
如果您不打算替换第6个字段
NA
内的所有出现的,而只是将其替换为,那么可以简化为:Na
NA
请注意
(?!\S)
负向预测运算符,它检查后面NA
是否跟着非空格,如果没有非空格,它也会替换NAPOLEON
为NaPOLEON
。甚至
sed
可以比那里更容易做到awk
:使用 GNU
sed
或兼容版本,你可以像在 perl 中一样使用\s
/\S
来代替[[:space:]]
/[^[:space:]]
。GNUsed
(以及一些其他版本,尽管有时具有不兼容的接口)还支持-i
ni
处编辑perl
。-E
现在是标准,并被大多数实现所支持sed
。如果你使用的是一个不支持它的非常旧的系统,你可以将其更改为:处理空格分隔字段同时保留间距的更通用方法是将输入分解为字段列表和空格分隔符字符串。
例如,将其分解为 17 个“领域”:
您之前的第6 个字段在新的细分中将成为第 12个。
在
perl
(请注意,@rrays 从 0 开始索引,因此第12 个字段变成$F[11]
):请注意,我们允许第一个“字段”为空,方法是使用 对其进行特殊处理
^\s*
,而所有其他字段都必须为非空(\s+
至少有一个空格字符)。请注意,在perl -n/-p
sed 模式(或-a
wk 模式)下,除非您传递-l
选项,否则换行符分隔符将包含在模式空间中($_
),因此它将是此处最后一个空格“字段”的一部分(上例中为第17 个)。