了解OFS在AWK中的工作方式

时间:2019-04-27 05:02:28

标签: awk

这是my question的后续行动,以更多地了解AWK中的OFS。

我的理解是,请在开始时设置一次,它将在“打印”中用于分隔各个字段。但是,正如我最初的问题中所述,它没有按预期运行。

我的文件:someone.txt

LN_A,FN_A<aa@xyz.com>;
LN_B,FN_B<bb@xyz.com>;

预期输出:

FN_A,LN_A,aa
FN_B,LN_B,bb 

我尝试了以下方法:

awk -F'[,<@]' -v OFS=',' '{print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' 'NF=3 {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' 'NF=3; {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' '{$1=$1} {print $2 $1 $3}' someone.txt
awk -F'[,<@]' -v OFS=',' '{$1=$1} {print $0}' someone.txt

最后,我设法通过以下方法获得所需的输出:

awk -F'[,<@]' '{print $2 "," $1 "," $3}' someone.txt

3 个答案:

答案 0 :(得分:2)

考虑以下情况:

a) $ echo '1 2 3' | awk '{print}'
1 2 3

b) $ echo '1 2 3' | awk '{print $1, $2, $3}'
1 2 3

c) $ echo '1 2 3' | awk -v OFS=',' '{print}'
1 2 3

d) $ echo '1 2 3' | awk -v OFS=',' '{print $1, $2, $3}'
1,2,3

e) $ echo '1 2 3' | awk -v OFS=',' '{$1=$1; print}'
1,2,3

上面的示例显示了OFS在“ b”和“ d”中(当各个字段以逗号分隔的列表打印时)和在“ e”中(当记录$ 0作为值的结果被重建时)在记录打印之前被分配给一个字段。

这是隐式使用OFS的仅有两次-打印逗号分隔的值列表和重建记录时。

当您按照上方“ a”和“ c”的方式打印记录(例如,按printprint $0进行打印或打印任何其他字符串时,您未使用OFS 。 OFS可能早已用于重建记录,如上面的“ e”所示,但打印不是逗号分隔的列表的任何操作都不使用OFS,它只是打印任何旧字符串,在这种情况下恰好是$ 0。

注意:

  1. 使用字段之间的OFS显式更改字段可从现有字段中重建$ 0,它不会再次将$ 0拆分为字段,因此在此过程中不使用FS。因此,$ 1 = $ 1或sub(/ 1 /,2,$ 1)使用OFS而不使用FS。
  2. 显式更改$ 0(即不是由于上述1而隐含地)将$ 0拆分为使用FS作为分隔符的字段,它不以任何方式使用OFS。因此$ 0 = $ 0或sub(/ 1 /,2)使用FS但不使用OFS。

了解FS和OFS如何协同工作以及如何影响对字段和$ 0的分配非常重要。如果您可以解释这种行为,那么您已经知道了:

f) $ echo 'a b' | awk -v OFS=',' '{print NF, $0, $1, $2}'
2,a b,a,b

g) $ echo 'a b' | awk -v OFS=',' '{$1=$1; print NF, $0, $1, $2}'
2,a,b,a,b

h) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; print NF, $0, $1, $2}'
1,a,b,a,b,

i) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; print NF, $0, $1, $2}'
1,a,b,a,b,

j) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; $1=$1; print NF, $0, $1, $2}'
1,a,b,a,b,

k) $ echo 'a b' | awk -v OFS=',' '{$1=$1; $0=$0; FS=OFS; $1=$1; $0=$0; print NF, $0, $1, $2}'
2,a,b,a,b

否则请随时提出问题。

答案 1 :(得分:1)

很简单,您已经在OFS=","语句的开头设置了awk,但是您只是在打印字段(注意:无需编辑行,也无需提及字段分隔符(使用逗号等) ),那么OFS将不会出现在图片中,这就是为什么您的输出没有分隔符之类的原因。

awk -F'[,<@]' -v OFS=',' '{print $2,$1,$3}' Input_fie

如果您在打印字段之间使用,时所使用的上述命令,您会发现您现在正在获得OFS,这就是它的工作方式。



或者,如果您想使用OFS,可以使用此方法(尽管上述解决方案是最佳方案,但出于您的理解,我也将其添加进来)。

awk -F'[,<@]' -v OFS=',' '{$0=$2 OFS $1 OFS $3} 1'  Input_file


通过打印整行来理解OFS的示例: 让我们通过使用OFS and without OFS打印整行来更清楚地了解它效果。

让我们运行以下代码:

awk -F'[,<@]' -v OFS=',' 'FNR==1{$1=$1} 1'  Input_file

当行号为1时,它的工作就是如上所述重置$1的值,使OFS出现在画面中,从而使{{1 }}来了(当然,无论在何处选择字段分隔符,都将在其中放置OFS值)。因此,仅对第一行和其余的REST进行任何操作。让我们看看现在输出什么?

OFS

您看到区别了吗?看到第一行在输出中有LN_A,FN_A,aa,xyz.com>; LN_B,FN_B<bb@xyz.com>; ,第二行照原样打印,为什么,因为仅在第一行中我们编辑了第一字段,所以,就变成了图片。

答案 2 :(得分:1)

正如我刚刚发现未使用的Aho,Kernighan和Weinberger的副本一样: 1988年的AWK编程语言,我将带您进入源代码(第35-36页):< / p>

字段变量。当前输入行的字段称为$1$2, 通过$NF$0代表整行。字段共享其他属性 变量-它们可以用于算术运算或字符串运算,并且可以是 分配给。 --

一个人可以为一个字段分配一个新字符串:

    BEGIN                          { FS = OFS = "\t" }
    $4 == "North America"          { $4 = "NA" }
    $4 == "South America"          { $4 = "SA" }
                                   { print }

在此程序中,BEGIN操作设置FS(控制输入的变量) 字段分隔符和OFS(输出字段分隔符)都放在一个标签中。 print 修改后的第四行中的语句打印$0的值 以前的作业。 这很重要:当$0通过分配或 替换$1$2等,并将NF重新计算;同样,当更改$1$2等之一时,将使用$0重构OFS以分隔字段。