使用 awk 进行系统调用

Making a system call with awk

我有一个包含数十万行的分隔文件,必须将其迁移到新系统。其中一个字段在新系统中是必需的,并且要求是唯一的,但在数据文件中经常丢失。为此,我想使用 awk 插入 uuid。我替换默认值的常规方法(假设缺少 $2)是

awk 'BEGIN{FS="\t"}{OFS="\t"}!{="defaultvalue"}1' myfile 

这适用于文本文字,但我想使用相同的机制在 awk 中使用命令替换。如果我从文件开始:

field1     requiredfield     field3
value1        networkId       value3
value2                        value4

所需的输出将是:

field1     requiredfield                        field3
value1        networkId                          value3
value2    6b34b312-8169-4539-b52f-a075542fb063   value4

我在其中使用 uuidgen 生成值。我几乎可以正常工作,但还不够

awk 'BEGIN{FS="\t"}{OFS="\t"}!{=system("uuidgen")}1'

returns 一个零和 uuidgen 输出

awk 'BEGIN{FS="\t"}{OFS="\t"}!{"uuidgen"|getline d}{=d}1'

awk -v uuid=$(uuidgen) 'BEGIN{FS="\t"}{OFS="\t"}!{=uuid}1'

零没有问题,但他们为所有记录提供相同的 uuid。我错过了什么?

假设你的输入文件是这样的:

cat -vte file

field1^Irequiredfield^Ifield3$
value1^InetworkId^Ivalue3$
value2^I ^Ivalue4$
value5^I ^Ivalue6$
value7^I ^Ivalue8$

您可以尝试此 awk 为每条记录运行给定的命令,并在内部命令失败时使用 shell 的输出:

cmd="uuidgen"

awk -v cmd="$cmd" -v uuid="$($cmd)" '
BEGIN {FS=OFS="\t"}
 ~ /^[[:blank:]]*$/ {
    = ((cmd | getline out) > 0 ? out : uuid)
   close(cmd)
} 1' file | column -t

field1  requiredfield                         field3
value1  networkId                             value3
value2  857063FB-673B-487B-8C00-6DF01537DA22  value4
value5  63333D5E-2156-4855-B8BC-CBB7CEF9E9F4  value6
value7  8CD16A13-F0F5-42E6-9998-3AA064F9B4FC  value8

column -t 已用于表格输出。