简体   繁体   English

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

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

On shell, I pipe to awk when I need a particular column.在 shell 上,当我需要特定的列时,我会通过管道传输到 awk。

This prints column 9, for example:这将打印第 9 列,例如:

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

How can I tell awk to print all the columns including and after column 9 , not just column 9?我如何告诉 awk 打印所有列,包括第 9和之后的所有列,而不仅仅是第 9 列?

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

When you want to do a range of fields, awk doesn't really have a straight forward way to do this.当您想要处理一系列字段时, awk并没有真正直接的方法来执行此操作。 I would recommend cut instead:我会推荐cut代替:

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

Edit编辑

Added space field delimiter due to default being a tab.由于默认为制表符,因此添加了空格字段分隔符。 Thanks to Glenn for pointing this out感谢格伦指出这一点

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

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

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

Instead of dealing with variable width whitespace, replace all whitespace as single space.不是处理可变宽度的空格,而是将所有空格替换为单个空格。 Then use simple cut with the fields of interest.然后对感兴趣的领域使用简单的cut

It doesn't use awk so isn't germane but seemed appropriate given the other answers/comments.它不使用 awk,所以不是密切相关的,但考虑到其他答案/评论,它似乎是合适的。

Generally perl replaces awk/sed/grep et.通常 perl 替换 awk/sed/grep 等。 al., and is much more portable (as well as just being a better penknife).人,而且是便携(以及刚刚成为一个更好的小刀)。

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

Timtowtdi applies of course. Timtowtdi 当然适用。

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

This chops what is before the given field nr., N, and prints all the rest of the line, including field nr.N and maintaining the original spacing (it does not reformat).这会截断给定字段 nr., N 之前的内容,并打印该行的所有其余部分,包括字段 nr.N 并保持原始间距(不会重新格式化)。 It doesn't mater if the string of the field appears also somewhere else in the line, which is the problem with Ascherer's answer.字段的字符串是否也出现在行中的其他地方并不重要,这是 Ascherer 的答案的问题。

Define a function:定义一个函数:

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

And use it like this:并像这样使用它:

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

Output maintains everything, including trailing spaces For N=0 it returns the whole line, as is, and for n>NF the empty string输出保留所有内容,包括尾随空格 对于 N=0,它按原样返回整行,对于 n>NF 则返回空字符串

Here is an example of ls -l output:这是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

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

Using cut instead of awk and overcoming issues with figuring out which column to start at by using the -c character cut command.使用 cut 而不是 awk 并解决了使用 -c 字符 cut 命令确定从哪一列开始的问题。

Here I am saying, give me all but the first 49 characters of the output.我的意思是,给我输出的前 49 个字符以外的所有字符。

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

The /*/*/ at the end of the ls command is saying show me what is in subdirectories too. ls 命令末尾的/*/*/表示也显示子目录中的内容。

You can also pull out certain ranges of characters ala (from the cut man page).您还可以拉出某些范围的字符 ala(来自剪切手册页)。 Eg, show the names and login times of the currently logged in users:例如,显示当前登录用户的姓名和登录时间:

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

To display the first 3 fields and print the remaining fields you can use:要显示前 3 个字段并打印剩余的字段,您可以使用:

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

where $1 $2 $3 are the first 3 fields.其中 $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
}

Usually it is desired to pass the remaining columns unmodified .通常希望通过未修改的剩余列。 That is, without collapsing contiguous white space.也就是说,不会折叠连续的空白区域。

Imagine the case of processing the output of ls -l or ps faux (not recommended, just giving examples where the last column may contain sequences of whitespace)).想象一下处理ls -lps faux输出的情况(不推荐,仅举例说明最后一列可能包含空格序列))。 We'd want any contiguous white space in the remaning columns preserved so that a file named my file.txt doesn't become my file.txt .我们希望保留剩余列中的任何连续空白,以便名为my file.txt的文件不会成为my file.txt

Preserving white space for the remainder of the line is surprisingly difficult using awk .使用awk为行的其余部分保留空白非常困难。 The accepted awk-based answer does not, even with the suggested refinements.即使有建议的改进,接受的基于 awk 的答案也没有。

sed or perl are better suited to this task. sedperl更适合此任务。

sed sed

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

Result:结果:

9   10

The -E option enables modern ERE regex syntax. -E选项启用现代 ERE 正则表达式语法。 This saves me the trouble of backslash escaping the parentheses and braces.这为我省去了反斜杠转义括号和大括号的麻烦。

The {8} is a quantifier indicating to match the previous item exactly 8 times. {8}是一个量词,表示与前一项精确匹配 8 次。

The sed s command replaces 8 occurrences of white space delimited words by an empty string. sed s命令用空字符串替换 8 次出现的以空格分隔的单词。 The remainder of the line is left intact.该行的其余部分保持不变。

perl perl

Perl regex supports the \\h escape for horizontal whitespace. Perl 正则表达式支持水平空白的\\h转义。

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

Result:结果:

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

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

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