awk用空格打印从第n个到最后一个的所有列

时间:2015-04-08 12:30:14

标签: bash unix awk

我有以下输入文件:

a 1  o p
b  2 o p p
c     3 o p p  p

在最后一行中,最后一行p's之间有一个双倍空格, 和列有不同的间距

我使用了以下解决方案:Using awk to print all columns from the nth to the last

awk '{for(i=2;i<=NF;i++){printf "%s ", $i}; printf "\n"}'

并且工作正常,直到最后一列达到双倍空格并删除一个空格。

如何在使用awk时避免这种情况?

4 个答案:

答案 0 :(得分:4)

由于您想保留空格,请使用cut

$ cut -d' ' -f2- file
1 o p
2 o p p
3 o p p  p

或者例如从第4列开始:

$ cut -d' ' -f4- file
p
p p
p p  p

只要您要删除的列是一个空格分隔的,这将有效。


如果要删除的列也包含不同的空格,您可以使用Ed Morton在Print all but the first three columns中的漂亮解决方案:

awk '{sub(/[[:space:]]*([^[:space:]]+[[:space:]]+){1}/,"")}1'
                                                   ^
                                        number of cols to remove

测试

$ cat a
a 1 o p
b    2 o p p
c  3 o p p  p
$ awk '{sub(/[[:space:]]*([^[:space:]]+[[:space:]]+){2}/,"")}1' a
o p
o p p
o p p  p

答案 1 :(得分:3)

GNU sed

删除前n个字段

sed -r 's/([^ ]+ +){2}//' file

GNU awk 4.0 +

awk '{sub("([^"FS"]"FS"){2}","")}1' file

GNU awk&lt; 4.0

awk --re-interval '{sub("([^"FS"]"FS"){2}","")}1' file

Incase FS一个不起作用(编辑建议)

awk '{sub(/([^ ] ){2}/,"")}1' file

将2替换为您要删除的字段数

修改

另一种方式(不需要重新间隔)

awk '{for(i=0;i<2;i++)sub($1"[[:space:]]*","")}1' file

进一步编辑

正如EdMorton所建议的那样,在sub中使用字段是不好的,因为它们可能包含元字符,所以这里有另一种选择(再次!)

awk '{for(i=0;i<2;i++)sub(/[^[:space:]]+[[:space:]]*/,"")}1' file

输出

o p
o p p
o p p  p

答案 2 :(得分:2)

在Perl中,您可以使用split进行捕获以保留分隔符:

perl -ne '@f = split /( +)/; print @f[ 1 * 2 .. $#f ]'
#                                      ^
#                                      |
#                              column number goes
#                              here (starting from 0)

答案 3 :(得分:1)

如果您希望在第二列开始后保留 所有 空格,则可以解决此问题:

{
    match($0, ($1 "[ \\t*]+"))
    print substr($0, RSTART+RLENGTH)
}

匹配调用定位行上第一个“标记”的开头,以及第一个标记的长度和后面的空格。然后,您只需在 之后 行打印所有内容。

你可以稍微概括一下,以这种方式忽略前N个代币:

BEGIN {
    N = 2
}

{
    r = ""
    for (i=1; i<=N; i++) {
        r = (r $i "[ \\t*]+")
    }
    match($0, r)
    print substr($0, RSTART+RLENGTH)
}

将上述脚本应用于示例输入会产生:

o p
o p p
o p p  p