我想在每行前面加上一个数字,说明该行有多少个斜杠。
awk '{ l=$0; gsub("[^/]","",l); print length(l),l }'
这不起作用,因为l=$0
似乎是通过引用分配的。我如何dup
串?
有没有更好的方法使用标准 UNIX 工具来完成此操作?我本质上想按深度(斜杠计数)对文件路径列表进行排序。
答案1
不,awk
始终按值分配,而不是按引用分配。
这右心轴变量赋值是一个表达,并且表达式 inawk
总是返回一个值。要复制变量,只需将其值分配给新变量,即可对新变量进行操作,而无需影响原始变量。
在:
$ echo 1 | awk '{l=$0; sub("1","2",l); print l, $0}'
2 1
l
仅修改了值,$0
值没有改变。
根据问题中的要求,只需执行以下操作:
awk -F '/' '{print NF-1, $0}' <file
您不需要做任何解析工作,awk
在您进入脚本主体之前,让我们为您完成所有工作。您只需提取信息即可。
答案2
根据手册:
gsub(regexp, replacement [, target])
(如果省略目标,则默认为$0
)。gsub()
返回进行的替换次数,因此在您的情况下您需要替换斜杠来获取计数:
awk '{l=$0; print gsub("/", ""), l}'
但正如 Etan Reisner 所注意到的,在这种情况下甚至不需要分配:
awk '{print gsub("/", "/"), $0}'
答案3
改用split
:
split(s, a[, fs ])
Split the string s into array elements a[1], a[2], ..., a[n],
and return n. All elements of the array shall be deleted
before the split is performed. The separation shall be done
with the ERE fs or with the field separator FS if fs is not
given. [. . .]
因此,给定这个输入文件:
$ cat file
no slashes
one / slash
two / and /
consecutive 3 ///
none
one /
你可以这样做:
$ awk '{ n=split($0,a,"/"); print n-1,$0}' file
0 no slashes
1 one / slash
2 two / and /
3 consecutive 3 ///
0 none
1 one /