这是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
答案 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”的方式打印记录(例如,按print
或print $0
进行打印或打印任何其他字符串时,您未使用OFS 。 OFS可能早已用于重建记录,如上面的“ e”所示,但打印不是逗号分隔的列表的任何操作都不使用OFS,它只是打印任何旧字符串,在这种情况下恰好是$ 0。
注意:
了解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
以分隔字段。”