awk - 在字段中替换后,awk 中的输出字段分隔符

标签 awk

修改awk中的特定字段后,总是这样吗? ,那个关于输出字段分隔符的信息丢失了?如果有多个字段分隔符并且我希望它们被恢复会发生什么?

例如,假设我有一个简单的文件 example其中包含:

a:e:i:o:u

如果我只是运行 awk脚本,它考虑了输入字段分隔符,打印文件中的每一行,例如运行
awk -F: '{print $0}' example

我会看到原线。但是,如果我直接修改其中一个字段,例如和
awk -F: '{$2=$2"!"; print $0}' example

我没有取回原始行的修改版本,而是看到由默认空格分隔符分隔的字段,即:
a e! i o u

我可以通过指定 OFS 取回原始版本的修改版本,例如:
awk -F: 'BEGIN {OFS=":"} {$2=$2"!"; print $0}' example

但是,在有多个势场分隔符但有多个分隔符的情况下,是否有一种简单的方法可以恢复原始分隔符?

例如,如果 example两者都有 :;作为分隔符,我可以使用 -F":|;"处理文件,但 OFS 不足以恢复原始分隔符的相对位置。

更明确地说,如果我们切换到 example2包含
a:e;i:o;u

我们可以使用
awk -F":|;" 'BEGIN {OFS=":"} {$2=$2"!"; print $0}' example2

(或 -F"[:;]" )获得
a:e!:i:o:u

但是我们已经失去了 : 和 ; 之间的区别。如果我们可以恢复,它会被维持
a:e!;i:o;u

最佳答案

您需要将 GNU awk 用于 split() 的第 4 个 arg 以保存分隔符,就像 RT 对 RS 所做的那样:

$ awk -F'[:;]' '{split($0,f,FS,s); $2=$2"!"; r=s[0]; for (i=1;i<=NF;i++) r=r $i s[i]; $0=r} 1' file
a:e!;i:o;u

没有自动填充的 FS 匹配字符串数组,因为每次将记录拆分为字段时,存储与 FS 匹配的字符串所需的时间和内存非常昂贵。相反,GNU awk 人员为 split() 提供了第四个参数,因此您可以在需要时/在需要时自行完成。这是几年前在 comp.lang.awk 新闻组中经验丰富的 awk 用户和 gawk 提供者之间的长时间对话的结果,之后所有人都同意这是最好的方法。

split()https://www.gnu.org/software/gawk/manual/gawk.html#String-Functions .

关于awk - 在字段中替换后,awk 中的输出字段分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38190358/

相关文章:

regex - Bash 替换文件中的 '\n\n}' 字符串

awk - 如何在 unix 中基于一个匹配列合并两个 csv 文件。两个文件中列的位置不同

awk - 如何在 awk 中将分隔字符串拆分为数组?

bash - 将 CSV 拆分为以其中一列命名的文件

awk 打印文件中每一行和下一行的字段

linux - 如何将制表符附加到文本文件中每一行的末尾

将毫秒转换为天的 Bash 脚本 :Hours:Minutes:Seconds:Milliseconds

awk - 根据csv文件的列值过滤行

postgresql - 我想将这些列解析为 psql 表,但如何处理空字段?

awk - 如何迭代匹配模式的循环并使用 awk 打印计数