如果文件中有'n'列,如何使用unix中的awk命令从第3列打印到最后列。我正在使用cut命令,但我需要awk命令。我正在尝试使用awk -F " " '{ for{i=3;i<=NF;i++) print $i}'
,我正在获取输出,但格式不正确。任何人都可以建议我正确的命令。
答案 0 :(得分:2)
将Ed Morton的答案结合在一起:
我们得到这样的东西:
awk '{sub(/^(\S+\s*){2}/,""); sub(/(\s*\S+){2}$/,"")}1'
# ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
# remove 2 first cols remove 2 last cols
您可以根据列来适应您的确切需求。
请参阅此输入的示例:
$ 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
我们打印第3栏:
$ 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
答案 1 :(得分:1)
假设你的字段是空格分隔的,那么使用GNU awk for 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
一般情况下,从字段3到字段5进行打印,如果它们是空白的,请使用GNU awk再次使用gensub()分隔:
$ awk '{print gensub(/(\S\s){2}((\S\s){2}\S).*/,"\\2",1)}' file
c d e
i j k
或第3个arg匹配():
$ awk 'match($0,/(\S\s){2}((\S\s){2}\S)/,a){print a[2]}' file
c d e
i j k
或者一般来说,如果它们被任何一个字符分开:
$ 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
如果字段由字符串而不是单字符分隔,但RS是单个字符,那么您应该暂时将FS更改为RS(根据定义,您知道记录中不能存在),这样您就可以在括号表达式中否定它:
$ 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
如果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
如果需要,显然可以在上面的最终gsub()中将FS改为OFS。
如果FS是regexp而不是字符串,并且你想在输出中保留它,那么你需要查看GNU awk以获得第4个arg for split()。
答案 2 :(得分:0)
如果你不介意规范空间,最直接的方法是
$ 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
行动
$ 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
输入
load
答案 3 :(得分:0)
您的尝试已接近但似乎会在新行上打印每一列。 为了纠正这个问题,我们创建了一个名为&#39; line&#39;并将其初始化为空字符串。我们第一次进入循环时只需将列添加到&#39; line&#39;。从那时起,我们将附加到&#39; line&#39;使用字段分隔符和下一列。最后,我们打印&#39; line&#39;。这将发生在文件中的每一行。
awk '{line="";for(i=3;i<=NF;i++) if(i==3) line=$i; else line=line FS $i; print line}'
在这个例子中,我假设使用awk的默认字段分隔符。任何小于3的行都会打印空白行。
答案 4 :(得分:0)
从第三列打印到结束然后 cat filename | awk&#39; {for(i = 1; i&lt; 3; i ++)$ i =&#34;&#34 ;; print $ 0}&#39;