Awk 打印除前三列以外的所有列

Awk 打印除前三列以外的所有列,awk,Awk,太麻烦了: awk '{print " "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13}' things 试试这个: awk '{ $1=""; $2=""; $3=""; print $0 }' echo 1 2 3 4 5 | awk'{for(i=3;i使用cut $ cut -f4-13 file 或者如果你坚持awk,最后一个字段是13美元 $ awk '{$1=$2=$3="";print}' file 否则 awk'

太麻烦了:

awk '{print " "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13}' things
试试这个:

awk '{ $1=""; $2=""; $3=""; print $0 }'
echo 1 2 3 4 5 | awk'{for(i=3;i使用cut

$ cut -f4-13 file
或者如果你坚持awk,最后一个字段是13美元

$ awk '{$1=$2=$3="";print}' file
否则


awk'{for(i=4;i
awk'{for(i=1;i避免使用print语句的另一种方法:

 $ awk '{$1=$2=$3=""}sub("^"FS"*","")' file

在awk中,当条件为真时,打印是默认操作。

不添加额外前导或尾随的解决方案:

提供了一种在字段之间保留原始空白的解决方案:

$ echo '1   2 3 4   5    6 7' |
  awk '{ sub(/([^ ]+ +){3}/,"") }1' |
  tr ' ' '-'
4---5----6-7
还提供了两个很棒的解决方案:
(这些解决方案甚至保留原始字符串的尾随空格)

  • 举例

    $echo'1234567'
    
    awk'{for(i=4;i目前几乎所有答案都添加了前导空格、尾随空格或其他一些分隔符问题。要使用
    awk
    从第四个字段中选择分隔符为空白且输出分隔符为单个空格,请执行以下操作:

    awk '{for(i=4;i<=NF;i++)printf "%s",$i (i==NF?ORS:OFS)}' file
    

    awk'{for(i=4;i执行此操作的正确方法是使用RE间隔,因为它允许您简单地说明要跳过多少字段,并保留其余字段的字段间距

    e、 g.鉴于我们在本问题中讨论的输入格式,在不影响剩余字段间距的情况下跳过前3个字段的步骤很简单:

    $ echo '1   2 3 4   5    6' |
    awk '{sub(/([^ ]+ +){3}/,"")}1'
    4   5    6
    
    如果您想容纳前导空格和非空格,但又使用默认的FS,那么它是:

    $ echo '  1   2 3 4   5    6' |
    awk '{sub(/[[:space:]]*([^[:space:]]+[[:space:]]+){3}/,"")}1'
    4   5    6
    

    如果你有一个FS,你不能在字符集中否定它,你可以先将它转换成单个字符(RS是理想的,如果它是单个字符,因为RS不能出现在一个字段中,否则考虑子SEP),然后应用RE间隔子项,然后转换到OFS。例如,如果“.s”的链分隔字段:

    $ echo '1...2.3.4...5....6' |
    awk -F'[.]+' '{gsub(FS,RS);sub("([^"RS"]+["RS"]+){3}","");gsub(RS,OFS)}1'
    4 5 6
    
    显然,如果OFS是单个字符,并且它不能出现在输入字段中,则可以将其减少为:

    $ echo '1...2.3.4...5....6' |
    awk -F'[.]+' '{gsub(FS,OFS); sub("([^"OFS"]+["OFS"]+){3}","")}1'
    4 5 6
    

    然后,您会遇到与所有重新分配字段的基于循环的解决方案相同的问题—FSs被转换为OFSs。如果这是一个问题,您需要研究GNU awks的patsplit()函数。

    这与前面的一些答案相去甚远,但确实解决了几个问题:

    cols.sh

    #!/bin/bash
    awk -v s=$1 '{for(i=s; i<=NF;i++) printf "%-5s", $i; print "" }'
    
    或:

    这是1索引;如果您更喜欢零索引,请使用
    i=s+1

    此外,如果您想使用起始索引和结束索引的参数,请将文件更改为:

    #!/bin/bash
    awk -v s=$1 -v e=$2 '{for(i=s; i<=e;i++) printf "%-5s", $i; print "" }'
    

    %-5s
    将结果对齐为5个字符宽的列;如果这还不够,请增加数字,或者如果您不关心对齐,则使用
    %s
    (带空格)。

    基于AWK printf的解决方案避免了%问题,并且独特之处在于它不返回任何内容(无返回字符)如果要打印的列少于4列:

    awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
    

    awk'NF>3{for(i=4;i3{for(i=4;i3{for(i=4;i3{for(i=4;i我不敢相信没有人提供纯shell:

    while read -r a b c d; do echo "$d"; done < file
    
    读取时-r a b c d;执行回显“$d”;完成
    输入

    输出

    4 5 6 7
    

    不添加前导或尾随空格的Perl解决方案:

    perl -lane 'splice @F,0,3; print join " ",@F' file
    
    perl
    @F
    自动拆分数组从索引
    0
    开始,而awk字段从
    $1
    开始


    逗号分隔数据的Perl解决方案:

    perl -F, -lane 'splice @F,0,3; print join ",",@F' file
    

    Python解决方案:

    $ echo '1 2 3 4 5 6 7' | 
      awk '{for(i=n;i<=NF;i++)$(i-(n-1))=$i;NF=NF-(n-1);print $0}' n=4 | tr ' ' '-'
    4-5-6-7
    

    python-c“导入sys;[sys.stdout.write(''.join(line.split()[3:])+'\n'),用于sys.stdin]中的行”
    选项1到3有多个空格的问题(但很简单)。 这就是开发选项4和5的原因,它们处理多个空白没有问题。 当然,如果选项4或5与
    n=0
    一起使用,这两个选项都将保留任何前导空格,因为
    n=0
    意味着没有拆分

    选择1 简单剪切解决方案(使用单个分隔符):

    选择2 强制awk重新计算有时可以解决添加前导空格的问题(适用于某些版本的awk):

    $ echo '1 2 3 4 5 6 7 8' | awk '{ $1=$2=$3="";$0=$0;} NF=NF'
    4 5 6 7 8
    
    选择3 打印使用
    printf
    格式化的每个字段将提供更多控制:

    $ echo '    1    2  3     4   5   6 7     8  ' |
      awk -v n=3 '{ for (i=n+1; i<=NF; i++){printf("%s%s",$i,i==NF?RS:OFS);} }'
    4 5 6 7 8
    
    它还可用于交换给定计数的字段列表
    n

    $ echo '    1    2  3     4   5   6 7     8  ' |
      awk -v n=3 '{ a=gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1);
                    b=gensub("^(.*)("a")","\\1",1);
                    print "|"a"|","!"b"!";
                   }'
    |4   5   6 7     8  | !    1    2  3     !
    
    当然,在这种情况下,OFS用于分隔行的两个部分,字段的尾随空白仍然打印

    注1:
    [“FS”]*
    用于在输入行中允许前导空格。

    Cut有一个--complete标志,使其变得简单(快速)删除列。生成的语法与您要执行的操作类似,使解决方案更易于阅读/理解。补码也适用于您要删除非连续列的情况

    $ foo='1 2 3 %s 5 6 7'
    $ echo "$foo" | cut --complement -d' ' -f1-3
    %s 5 6 7
    $
    

    对我来说,最紧凑、最符合要求的解决方案是

    $ a='1   2\t \t3     4   5   6 7 \t 8\t '; 
    $ echo -e "$a" | awk -v n=3 '{while (i<n) {i++; sub($1 FS"*", "")}; print $0}'
    
    $a='12\t\t34567\t8\t';
    
    $echo-e“$a”| awk-vn=3'{(i当我对第一个投票率很高但错误的答案感到恼火时,我发现足以在那里写一个答复,这里错误的答案被标记为这样,这是我的一点。我不喜欢提议的解决方案,因为我看不出有理由让答案如此复杂

    我有一个日志,其中5美元后的IP地址可以是更多的文本或没有文本。我需要从IP地址到行尾的所有内容,如果5美元后有任何内容。在我的情况下,这实际上是一个awk程序,而不是一个awk单行程序,所以awk必须解决这个问题。当我尝试使用旧的美观和mo删除前4个字段时st投了赞成票,但回答完全错误:

    echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'
    
    它给出了错误且无用的回答(我添加了[]以证明):

    相反,如果列的宽度固定,直到需要切割点和awk,正确且非常简单的答案是:

    echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{printf "[%s]\n", substr($0,28)}'
    
    它产生所需的输出:

    [37.244.182.218 one two three]
    

    我发现了另一种可能性,也许它也有用

    awk'BEGIN{OFS=ORS=“\t”};{for(i=1;i使用cut:

    cut -d <The character between characters> -f <number of first column>,<number of last column> <file name>
    
    cut-d-f,
    
    e、 g:如果您有
    文件1
    包含:
    汽车.is.nice.equal.bmw

    运行:
    cut-d.-f1,3 file1
    将打印
    car.is.niceawk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
    
    $ x='1 2 3 %s 4 5 6'
    $ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
    %s 4 5 6
    $ x='1 2 3'
    $ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
    $ x='1 2 3 '
    $ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
    $
    
    while read -r a b c d; do echo "$d"; done < file
    
    awk '{$1=$2=$3="";$0=$0;$1=$1}1'
    
    1 2 3 4 5 6 7
    
    4 5 6 7
    
    perl -lane 'splice @F,0,3; print join " ",@F' file
    
    perl -F, -lane 'splice @F,0,3; print join ",",@F' file
    
    $ echo '1 2 3 4 5 6 7 8' | cut -d' ' -f4-
    4 5 6 7 8
    
    $ echo '1 2 3 4 5 6 7 8' | awk '{ $1=$2=$3="";$0=$0;} NF=NF'
    4 5 6 7 8
    
    $ echo '    1    2  3     4   5   6 7     8  ' |
      awk -v n=3 '{ for (i=n+1; i<=NF; i++){printf("%s%s",$i,i==NF?RS:OFS);} }'
    4 5 6 7 8
    
    $ echo '    1    2  3     4   5   6 7     8  ' |
    awk -v n=3 '{ for(i=1;i<=n;i++) { sub("^["FS"]*[^"FS"]+["FS"]+","",$0);} } 1 '
    4   5   6 7     8
    
    $ echo '    1    2  3     4   5   6 7     8  ' |
    awk -v n=3 '{ print gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1); }'
    4   5   6 7     8 
    
    $ echo '    1    2  3     4   5   6 7     8  ' |
      awk -v n=3 '{ a=gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1);
                    b=gensub("^(.*)("a")","\\1",1);
                    print "|"a"|","!"b"!";
                   }'
    |4   5   6 7     8  | !    1    2  3     !
    
    $ foo='1 2 3 %s 5 6 7'
    $ echo "$foo" | cut --complement -d' ' -f1-3
    %s 5 6 7
    $
    
    $ a='1   2\t \t3     4   5   6 7 \t 8\t '; 
    $ echo -e "$a" | awk -v n=3 '{while (i<n) {i++; sub($1 FS"*", "")}; print $0}'
    
    $ awk -v n=3 '{i=0; while (i<n) {i++; sub($1 FS"*", "")}; print $0}' foo.txt
    
    echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'
    
    [    37.244.182.218 one two three]
    
    echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{printf "[%s]\n", substr($0,28)}'
    
    [37.244.182.218 one two three]
    
    cut -d <The character between characters> -f <number of first column>,<number of last column> <file name>