繁体   English   中英

如何使用awk打印特定数字后的所有列?

[英]How to print all the columns after a particular number using awk?

在 shell 上,当我需要特定的列时,我会通过管道传输到 awk。

这将打印第 9 列,例如:

... | awk '{print $9}'

我如何告诉 awk 打印所有列,包括第 9和之后的所有列,而不仅仅是第 9 列?

awk '{ s = ""; for (i = 9; i <= NF; i++) s = s $i " "; print s }'

当您想要处理一系列字段时, awk并没有真正直接的方法来执行此操作。 我会推荐cut代替:

cut -d' ' -f 9- ./infile

编辑

由于默认为制表符,因此添加了空格字段分隔符。 感谢格伦指出这一点

awk '{print substr($0, index($0,$9))}'

编辑:注意,如果第九个之前的任何字段包含与第九个相同的值,这将不起作用。

sed -re 's,\s+, ,g' | cut -d ' ' -f 9-

不是处理可变宽度的空格,而是将所有空格替换为单个空格。 然后对感兴趣的领域使用简单的cut

它不使用 awk,所以不是密切相关的,但考虑到其他答案/评论,它似乎是合适的。

通常 perl 替换 awk/sed/grep 等。 人,而且是便携(以及刚刚成为一个更好的小刀)。

perl -lane 'print "@F[8..$#F]"'

Timtowtdi 当然适用。

awk -v m="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

这会截断给定字段 nr., N 之前的内容,并打印该行的所有其余部分,包括字段 nr.N 并保持原始间距(不会重新格式化)。 字段的字符串是否也出现在行中的其他地方并不重要,这是 Ascherer 的答案的问题。

定义一个函数:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

并像这样使用它:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost   

输出保留所有内容,包括尾随空格 对于 N=0,它按原样返回整行,对于 n>NF 则返回空字符串

这是ls -l输出的示例:

-rwxr-----@ 1 ricky.john  1493847943   5610048 Apr 16 14:09 00-Welcome.mp4
-rwxr-----@ 1 ricky.john  1493847943  27862521 Apr 16 14:09 01-Hello World.mp4
-rwxr-----@ 1 ricky.john  1493847943  21262056 Apr 16 14:09 02-Typical Go Directory Structure.mp4
-rwxr-----@ 1 ricky.john  1493847943  10627144 Apr 16 14:09 03-Where to Get Help.mp4

我打印$9后任何内容的解决方案是awk '{print substr($0, 61, 50)}'

使用 cut 而不是 awk 并解决了使用 -c 字符 cut 命令确定从哪一列开始的问题。

我的意思是,给我输出的前 49 个字符以外的所有字符。

 ls -l /some/path/*/* | cut -c 50-

ls 命令末尾的/*/*/表示也显示子目录中的内容。

您还可以拉出某些范围的字符 ala(来自剪切手册页)。 例如,显示当前登录用户的姓名和登录时间:

       who | cut -c 1-16,26-38

要显示前 3 个字段并打印剩余的字段,您可以使用:

awk '{s = ""; for (i=4; i<= NF; i++) s= s $i : "; print $1 $2 $3 s}' filename

其中 $1 $2 $3 是前 3 个字段。

function print_fields(field_num1, field_num2){
    input_line = $0

    j = 1;
    for (i=field_num1; i <= field_num2; i++){
        $(j++) = $(i);

    }
    NF = field_num2 - field_num1 + 1;
    print $0

    $0 = input_line
}

通常希望通过未修改的剩余列。 也就是说,不会折叠连续的空白区域。

想象一下处理ls -lps faux输出的情况(不推荐,仅举例说明最后一列可能包含空格序列))。 我们希望保留剩余列中的任何连续空白,以便名为my file.txt的文件不会成为my file.txt

使用awk为行的其余部分保留空白非常困难。 即使有建议的改进,接受的基于 awk 的答案也没有。

sedperl更适合此任务。

sed

echo '1 2 3 4 5 6 7 8 9   10' | sed -E 's/^([^ \t]*[ \t]*){8}//'

结果:

9   10

-E选项启用现代 ERE 正则表达式语法。 这为我省去了反斜杠转义括号和大括号的麻烦。

{8}是一个量词,表示与前一项精确匹配 8 次。

sed s命令用空字符串替换 8 次出现的以空格分隔的单词。 该行的其余部分保持不变。

perl

Perl 正则表达式支持水平空白的\\h转义。

echo '1 2 3 4 5 6 7 8 9   10' | perl -pe 's/^(\H*\h*){8}//'

结果:

9   10
ruby -lane 'print $F[3..-1].join(" ")' file

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM