以编程方式更改字段分隔符(FS)并重新计算 gawk 中的当前记录?

Seb*_*los 4 awk

我只想更改特定记录的字段分隔符 ( ),并且希望使用新的字段分隔符重新计算FS记录 ( $0)、字段 ( $N) 和字段数 ( )。NF但这似乎不起作用。

示例:这里有一行被解释为由空格分隔的三个字段。如果我将字段分隔符更改为n并强制重新构建记录 ( $1 = $1),则记录保持不变,如打印所示$1

$ echo 'one two three' | awk '1 {FS="n" ; OFS=":" ; $1 = $1 ; print $1}'
> one
Run Code Online (Sandbox Code Playgroud)

但我希望输出是:

> o
Run Code Online (Sandbox Code Playgroud)

通过运行强制重新构建记录的技巧$1 = $1取自gawk手册。所以我希望它能起作用。我不确定可能是什么问题:

尝试简单地通过设置FS和 来更改记录中的字段分隔符OFS,然后期望一个普通的printprint $0打印修改后的记录,这是一个常见的错误。

但这不起作用,因为没有采取任何措施来更改记录本身。相反,您必须强制重建记录,通常使用诸如$1 = $1[...]

(我使用的是 GNU Awk 5.2.2)

Ed *_*ton 10

关于

我只想更改特定记录的字段分隔符 (FS)

如果您使用split()该记录,您的代码可能会更清晰/更简单。

您混淆了 2 个概念 - 重建 $0 和重新分割 $0。

重建 $0:当您修改或以其他方式为字段赋值时,$0 将从字段中重建,将每个 FS 替换为 OFS,例如

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $1 = $1 ; print; for (i=1; i<=NF; i++) print i, $i}'
one:two:three
1:one
2:two
3:three
Run Code Online (Sandbox Code Playgroud)

重新分割 $0:当您修改或以其他方式为 $0 赋值(除了由于更改字段而重建它的结果)时,$0 将使用现有的 FS 值重新分割为字段,例如

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $0 = $0 ; print; for (i=1; i<=NF; i++) print i, $i}'
one two three
1:o
2:e two three
Run Code Online (Sandbox Code Playgroud)

现在尝试理解以下结果,看看您是否理解了上面的陈述:

重建然后重新分割:

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $1 = $1 ; $0 = $0; print; for (i=1; i<=NF; i++) print i, $i}'
one:two:three
1:o
2:e:two:three
Run Code Online (Sandbox Code Playgroud)

重新分割然后重建:

$ echo 'one two three' |
    awk '{FS="n" ; OFS=":" ; $0 = $0; $1 = $1 ; print; for (i=1; i<=NF; i++) print i, $i}'
o:e two three
1:o
2:e two three
Run Code Online (Sandbox Code Playgroud)


mur*_*uru 7

环顾引用的文字,我看到:

最后,有时awk使用字段 和 的当前值强制重建整个记录是很方便的OFS

稍后接着是:

$0和领域之间的关系也有另一面。对 的任何赋值都会导致使用 的当前$0将记录重新解析为字段。FS

从前一句中没有提及FS以及第二句中的强调来看,我认为预期的方式是仅$0 = $0会导致字段被重新计算;其他只会导致记录根据字段值的输出而更改,而不会尝试解析它们:

% echo 'one two three' | awk '1 {FS="n" ; OFS=":" ; $0 = $0 ; print $1}'
o

% echo 'one two three' | awk '{FS="n" ; OFS=":" ; $1 = $1 ; print}'
one:two:three
Run Code Online (Sandbox Code Playgroud)

请注意,我没有使用 GNU awk:

% awk --version
awk version 20200816
Run Code Online (Sandbox Code Playgroud)

但我希望 GNU awk 也能如此。