如何用awk保持一行中whitspace的数量不变?

时间:2017-08-10 02:54:38

标签: bash awk whitespace

我想获得/ etc / sudoers中最长的一行 对于wc。

sudo wc -L /etc/sudoers
90 /etc/sudoers

对于awk

sudo awk '{if(length>L){L=length;s=$0}}END{print NR,L,s}'  /etc/sudoers
27 83 Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

awk将第27行中的8个空格视为1个空格,8-1 = 7,90-83 = 7。 因此wc的数字比awk大7 如何使awk中的whitspace数保持不变,使awk在第27行中保持8个空格不变,而不是1。 如何修复命令sudo awk '{if(length>L){L=length;s=$0}}END{print NR,L,s}' /etc/sudoers,用awk输出以下结果。

27 90 Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

2 个答案:

答案 0 :(得分:1)

这可能是因为该文件包含标签。

  

使用--max-line-length' option, wc'打印的长度   每个文件最长的行,如果有多个文件则打印   这些长度的最大值(不是总和)。这里的线长是   根据当前区域设置在屏幕列中测量   假设第8列中的标签位置。

所以wc假设每个标签的宽度为8.我们必须在awk中模拟这个。标签仅出现在行首的一个特殊情况很容易修复。

sudo awk '{sub("\t","        ") ; 
    if(length>L){L=length;s=$0}}END{print NR,L,s}' /etc/sudoers

答案 1 :(得分:1)

/ etc / sudoers中行的最大长度包含一个标签,正如您从文件的hexdump中看到的那样,

$ sudo cat /etc/sudoers | hexdump -C
...
...
00000110  73 73 0a 44 65 66 61 75  6c 74 73 09 73 65 63 75  |ss.Defaults.secu|
...
...

您可能会在2秒(十六进制:73)之间看到09。并查看ascii表,它将是 水平标签

您可以从@Dmitri Chubarov的回答中看到,wc会将'\t'的长度视为8。

使awk输出与wc -L相同结果的另一种方法可以是,

$ sudo awk '{if(length>L){L=7*(match($0,/\t/)?1:0)+length;s=$0}}END{print NR,L,s}' /etc/sudoers
30 100 Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

函数match($0,/\t/)?1:0将返回1任何\t存在,如果是,则添加7作为长度。