在浏览一段代码时,我看到了以下命令:
grep "r" temp | awk '{FS=","; $0=$0} { print $1,$3}'
临时文件包含如下模式:
1. r,1,5
2. r,4,5
3. ...
我无法理解语句$0=$0
在awk命令中的含义。
任何人都可以解释它是什么意思吗?
答案 0 :(得分:3)
$0 = $0
最常用于重建已修改条目的字段分离评估。例如:在$ 0 = $ 0之后添加一个字段将改变$ NF,它保持原始状态(在该行的入口处)。
在这种情况下,将字段分隔符的每一行更改为(请参阅下面的@EdMorton注释以获取警示)使用当前FS重新分析该行info ,
和awk -F ',' { print $1 "," $3 }'
更好地编码同一个想法的信息,在开始所有行时采用字段分隔符(在这种情况下,如果在通过前一行内容的示例处理depernding期间修改了分隔符,则可能会有所不同)< / p>
例如:
echo "foo;bar" | awk '{print NF}{FS=";"; print NF}{$0=$0;print NF}'
1
1
2
基于@EdMorton评论和相关帖子(What is the meaning of $0 = $0 in Awk)
echo "a-b-c" |\
awk ' BEGIN{ FS="-+"; OFS="-"}
function p(Ref) { printf "%12s) NF=%d $0=%s, $2=%s\n", Ref,NF,$0,$2 }
{
p("Org")
$2="-"; p( "S2=-")
$1=$1 ; p( "$1=$1")
$2=$2 ; p( "$2=$2")
$0=$0 ; p( "$0=$0")
$2=$2 ; p( "$2=$2")
$3=$3 ; p( "$3=$3")
$1=$1 ; p( "$1=$1")
} '
Org) NF=3 $0=a-b-c, $2=b
S2=-) NF=3 $0=a---c, $2=-
$1=$1) NF=3 $0=a---c, $2=-
$2=$2) NF=3 $0=a---c, $2=-
$0=$0) NF=2 $0=a---c, $2=c
$2=$2) NF=2 $0=a-c, $2=c
$3=$3) NF=3 $0=a-c-, $2=c
$1=$1) NF=3 $0=a-c-, $2=c
答案 1 :(得分:3)
当您执行$1=$1
(或对字段的任何其他分配)时,它会导致记录重新编译,其中每个FS替换为OFS重建$ 0,但它不会更改NF或以任何其他方式重新评估记录。 / p>
当你执行$0=$0
时,它会导致字段拆分,其中NF,$ 1,$ 2等根据FS的当前值重新填充,但它不会将FS更改为OFS或以任何其他方式修改$ 0。
查找
$ echo 'a-b-c' |
awk -F'-+' -v OFS='-' '
function p() { printf "%d) %d: $0=%s, $2=%s\n", ++c,NF,$0,$2 }
{ p(); $2=""; p(); $1=$1; p(); $0=$0; p(); $1=$1; p() }
'
1) 3: $0=a-b-c, $2=b
2) 3: $0=a--c, $2=
3) 3: $0=a--c, $2=
4) 2: $0=a--c, $2=c
5) 2: $0=a-c, $2=c
请注意,即使将$ 2设置为null也会导致连续2次-
,而-+
的FS意味着2 -
s是单个分隔符,但它们不是如此处理,直到$0=$0
导致记录被重新拆分为字段,如输出步骤4所示。
您拥有的代码:
awk '{FS=","; $0=$0}'
正在使用$0=$0
作为一个解决这个问题的事实,即在第一条记录被读取并分成字段之后它才设置FS:
$ printf 'a,b\nc,d\n' | awk '{print NF, $1}'
1 a,b
1 c,d
$ printf 'a,b\nc,d\n' | awk '{FS=","; print NF, $1}'
1 a,b
2 c
$ printf 'a,b\nc,d\n' | awk '{FS=","; $0=$0; print NF, $1}'
2 a
2 c
当然,正确的解决方案是简单地设置FS BEFORE读取第一条记录:
$ printf 'a,b\nc,d\n' | awk -F, '{print NF, $1}'
2 a
2 c
要清楚 - 将任何值分配给$ 0会导致字段拆分,它不会导致记录重新编译,同时将任何值分配给任何字段($ 1等)会导致记录重新编译但不会进行字段拆分:
$ echo 'a-b-c' | awk -F'-+' -v OFS='#' '{$2=$2}1'
a#b#c
$ echo 'a-b-c' | awk -F'-+' -v OFS='#' '{$0=$0}1'
a-b-c
答案 2 :(得分:1)
$0=$0
用于重新评估字段
例如
akshay@db-3325:~$ cat <<EOF | awk '/:/{FS=":"}/\|/{FS="|"}{print $2}'
1:2
2|3
EOF
# Same with $0=$0, it will force awk to have the $0 reevaluated
akshay@db-3325:~$ cat <<EOF | awk '/:/{FS=":"}/\|/{FS="|"}{$0=$0;print $2}'
1:2
2|3
EOF
2
3
# NF - gives you the total number of fields in a record
akshay@db-3325:~$ cat <<EOF | awk '/:/{FS=":"}/\|/{FS="|"}{print NF}'
1:2
2|3
EOF
1
1
# When we Force to re-evaluate the fields, we get correct 2 fields
akshay@db-3325:~$ cat <<EOF | awk '/:/{FS=":"}/\|/{FS="|"}{$0=$0; print NF}'
1:2
2|3
EOF
2
2
答案 3 :(得分:0)
>>> echo 'a-b-c' | awk -F'-+' -v OFS='#' '{$2=$2}1'
>>> a#b#c
这可以稍微简化为
mawk 'BEGIN { FS="[-]+"; OFS = "#"; } ($2=$2)'
Rationale是随后进行的布尔测试,将在分配后评估为true,因此它本身足以重新生成OFS中的字段并进行打印。