简体   繁体   English

AWK命令从第3列打印到第n列

[英]Awk command to print from 3rd column to till nth column

How to print from 3rd column to till last columns using awk command in unix, if there are 'n' columns in a file. 如果文件中有'n'列,如何使用UNIX中的awk命令从第三列打印到最后一列。 I am getting with cut command but I need awk command. 我正在使用cut命令,但是我需要awk命令。 I am trying to do with awk -F " " '{ for{i=3;i<=NF;i++) print $i}' , I am getting the output but it is not in the correct format. 我正在尝试使用awk -F " " '{ for{i=3;i<=NF;i++) print $i}' ,我正在获取输出,但格式不正确。 Can anyone suggest me the proper command. 谁能建议我正确的命令。

Combining Ed Morton's answers in: 结合Ed Morton的答案:

We get something like this: 我们得到这样的东西:

awk '{sub(/^(\S+\s*){2}/,""); sub(/(\s*\S+){2}$/,"")}1'
#     ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^
#     remove 2 first cols      remove 2 last cols

Which you can adapt to your exact needs in terms of columns. 您可以根据列来适应您的确切需求。

See an example given this input: 查看给出此输入的示例:

$ paste -d ' ' <(seq 5) <(seq 2 6) <(seq 3 7) <(seq 4 8) <(seq 5 9) 
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

Let's just print the 3rd column: 让我们只打印第三列:

$ awk '{sub(/^(\S+\s*){2}/,""); sub(/(\s*\S+){2}$/,"")}1' <(paste -d ' ' <(seq 5) <(seq 2 6) <(seq 3 7) <(seq 4 8) <(seq 5 9))
3
4
5
6
7

Assuming your fields are space-separated then with GNU awk for gensub(): 假设您的字段用空格分隔,然后使用GNU awk生成gensub():

$ cat file
a b c d e f
g h i j k l

$ awk '{print gensub(/(\S\s){2}/,"",1)}' file
c d e f
i j k l

In general to print from, say, field 3 to field 5 if they are blank separated using GNU awk again with gensub(): 通常,如果使用gensub()再次使用GNU awk将它们空白分隔,则从字段3到字段5进行打印:

$ awk '{print gensub(/(\S\s){2}((\S\s){2}\S).*/,"\\2",1)}' file
c d e
i j k

or the 3rd arg to match(): 或第三个arg匹配():

$ awk 'match($0,/(\S\s){2}((\S\s){2}\S)/,a){print a[2]}' file
c d e
i j k

or in general if they are separated by any single character: 或通常,如果它们之间用任何单个字符分隔:

$ awk '{print gensub("([^"FS"]"FS"){2}(([^"FS"]"FS"){2}[^"FS"]).*","\\2",1)}' file
c d e
i j k

$ awk 'match($0,"([^"FS"]"FS"){2}(([^"FS"]"FS"){2}[^"FS"])",a){print a[2]}' file
c d e
i j k

If the fields are separated by a string instead of a single-character but the RS is a single character then you should temporarily change FS to RS (which by definition you KNOW can't be present in the record) so you can negate it in the bracket expressions: 如果字段由字符串而不是单个字符分隔,但RS是单个字符,则应暂时将FS更改为RS(根据定义,您不能在记录中看到KNOW),以便可以将其取反。括号表达式:

$ cat file
aSOMESTRINGbSOMESTRINGcSOMESTRINGdSOMESTRINGeSOMESTRINGf
gSOMESTRINGhSOMESTRINGiSOMESTRINGjSOMESTRINGkSOMESTRINGl

$ awk -F'SOMESTRING' '{gsub(FS,RS)} match($0,"([^"RS"]"RS"){2}(([^"RS"]"RS"){2}[^"RS"])",a){gsub(RS,FS,a[2]); print a[2]}' file
cSOMESTRINGdSOMESTRINGe
iSOMESTRINGjSOMESTRINGk

If both the FS and the RS are multi-char then there's various options but the simplest is to use the NUL character or some other character you know can't appear in your input file instead of RS as the temporary replacement FS: 如果FS和RS都是多字符,则有多种选择,但是最简单的方法是使用NUL字符或您知道无法在输入文件中出现的其他字符代替RS作为临时替换FS:

$ awk -F'SOMESTRING' '{gsub(FS,"\0")} match($0,/([^\0]\0){2}(([^\0]\0){2}[^\0])/,a){gsub("\0",FS,a[2]); print a[2]}' file
cSOMESTRINGdSOMESTRINGe
iSOMESTRINGjSOMESTRINGk

Obviously change FS to OFS in the final gsub()s above if desired. 显然,如果需要,可以在上述最后的gsub()中将FS更改为OFS。

If the FS was a regexp instead of a string and you want to retain it in the output then you need to look at GNU awk for the 4th arg for split(). 如果FS是一个regexp而不是字符串,并且您希望将其保留在输出中,则需要查看GNU awk中split()的第4个参数。

Your attempt was close but appears that it would print each and every column on a new line. 您的尝试已结束,但似乎将在新行上打印每一列。 To correct this we create a variable called 'line' and initialize it to an empty string. 为了解决这个问题,我们创建了一个名为“ line”的变量,并将其初始化为一个空字符串。 The first time we are in the loop we just add the column to 'line'. 第一次进入循环时,我们只是将列添加到“行”中。 From that point on we will append to 'line' with the field separator and the next column. 从这一点开始,我们将使用字段分隔符和下一列追加到“行”后面。 Finally, we print 'line'. 最后,我们打印“行”。 This will happen for each line in the file. 这对于文件中的每一行都会发生。

awk '{line="";for(i=3;i<=NF;i++) if(i==3) line=$i; else line=line FS $i; print line}'

In this example I assume to use awk's default field separator. 在此示例中,我假设使用awk的默认字段分隔符。 Also any lines that are less than three will print blank lines. 同样,少于三行的任何行都会打印空白行。

If you don't mind normalizing the space, the most straightforward way is 如果您不介意标准化空间,最直接的方法是

$ awk '{$1=$2=""}1' | sed -r 's/^ +//'

in action 在行动

$ seq 11 40 | pr -6ts' ' | awk '{$1=$2=""}1' | sed -r 's/^ +//'

21 26 31 36
22 27 32 37
23 28 33 38
24 29 34 39
25 30 35 40

for the input 用于输入

$ seq 11 40 | pr -6ts' '

11 16 21 26 31 36
12 17 22 27 32 37
13 18 23 28 33 38
14 19 24 29 34 39
15 20 25 30 35 40

要从第三列打印到最后,请输入cat filename | awk'{for(i = 1; i <3; i ++)$ i =“”; print $ 0}'

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

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