使用awk打印除第一个字段以外的所有内容

cfi*_*her 96 perl awk sed

我有一个看起来像这样的文件:

AE  United Arab Emirates
AG  Antigua & Barbuda
AN  Netherlands Antilles
AS  American Samoa
BA  Bosnia and Herzegovina
BF  Burkina Faso
BN  Brunei Darussalam
Run Code Online (Sandbox Code Playgroud)

我想颠倒订单,先打印除1美元以外的所有商品,然后再打印1美元:

United Arab Emirates AE
Run Code Online (Sandbox Code Playgroud)

我怎么能做"除了场1之外的一切"技巧?

小智 102

$1=""像本杰克逊提到的那样留下一个空间,所以使用一个for循环:

awk '{for (i=2; i<=NF; i++) print $i}' filename
Run Code Online (Sandbox Code Playgroud)

所以如果你的字符串是"一二三",输出将是:

2
3

如果您希望结果在一行中,您可以执行以下操作:

awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' filename
Run Code Online (Sandbox Code Playgroud)

这会给你:"两个三"

  • 还有一个额外的尾随空间 (4认同)
  • 最好使用:`awk '{for(i=2;i&lt;=NF;i++){ printf("%s",( (i&gt;2) ? OFS : "" ) $i) } ; print ;}' ` which : 将字段 2 打印到 NF,根据需要添加输出字段分隔符(即,$2 之前除外)。最后一次打印添加最后一个换行符以结束当前行打印。如果您更改 FS/OFS(即,它并不总是“空间”),那将起作用 (2认同)

Ben*_*son 82

分配$1工作但会留下领先的空间:awk '{first = $1; $1 = ""; print $0, first; }'

您还可以NF在循环中找到列数并使用它.

  • 对于完全懒惰; 这是[klashxx'代码](http://stackoverflow.com/a/22908787/2192488). (2认同)
  • 伟大的。用 sed 去掉前导空格:`awk {'first = $1; $1=""; 打印 $0'}|sed 's/^ //g'` (2认同)
  • 要删除前导空格,您也可以使用 gsub : `awk '/&gt;/ {first = $1; $1=""; gsub(/^/,""); 首先打印 $0}' somefile` (2认同)

zel*_*niy 62

使用cut带以下--complement选项的命令:

$ echo a b c | cut -f 1 -d ' '
a
$ echo a b c | cut -f 1,2 -d ' '
a b
$ echo a b c | cut -f 1 -d ' ' --complement
b c
Run Code Online (Sandbox Code Playgroud)

  • `echo abc | cut -d'' - f 2-`是另一种选择 (15认同)
  • 虽然没有回答特定于awk的问题,但我发现这最有用,因为awk正在删除重复的空格,而cut则没有. (2认同)
  • 很好 - @Luis解决方案适用于Mac,它不支持 - 实现 (2认同)

Jua*_*doy 20

也许最简洁的方式:

$ awk '{$(NF+1)=$1;$1=""}sub(FS,"")' infile
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
Run Code Online (Sandbox Code Playgroud)

说明:

$(NF+1)=$1:"新"最后一个字段的生成器.

$1="":将原始第一个字段设置为null

sub(FS,""):在前两个操作之后{$(NF+1)=$1;$1=""},使用sub删除第一个字段分隔符.最后的印刷是隐含的.


Ner*_*elu 13

awk '{sub($1 FS,"")}7' YourFile
Run Code Online (Sandbox Code Playgroud)

删除第一个字段和分隔符,然后打印结果(7非零值,因此打印$ 0).


dub*_*jim 10

awk '{ saved = $1; $1 = ""; print substr($0, 2), saved }'
Run Code Online (Sandbox Code Playgroud)

将第一个字段设置""OFS在开头留下一个副本$0.假设这OFS只是一个字符(默认情况下,它是一个单独的空格),我们可以删除它substr($0, 2).然后我们附加保存的副本$1.


Chr*_*nat 5

如果您对Perl解决方案持开放态度......

perl -lane 'print join " ",@F[1..$#F,0]' file
Run Code Online (Sandbox Code Playgroud)

是一个简单的解决方案,具有一个空间的输入/输出分隔符,它产生:

United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
Run Code Online (Sandbox Code Playgroud)

下一个稍微复杂一些

perl -F`  ` -lane 'print join "  ",@F[1..$#F,0]' file
Run Code Online (Sandbox Code Playgroud)

并假设输入/输出分隔符是两个空格:

United Arab Emirates  AE
Antigua & Barbuda  AG
Netherlands Antilles  AN
American Samoa  AS
Bosnia and Herzegovina  BA
Burkina Faso  BF
Brunei Darussalam  BN
Run Code Online (Sandbox Code Playgroud)

使用这些命令行选项:

  • -n 循环输入文件的每一行,不要自动打印每一行

  • -l 在处理之前删除换行符,然后将其添加回来

  • -a自动分裂模式 - 将输入线分割为@F数组.默认为在空格上拆分

  • -F autosplit修饰符,在此示例中拆分''(两个空格)

  • -e 执行以下perl代码

@F是每行中的单词数组,以0开头的索引
$#F是单词@F
@F[1..$#F]1的数组中的单词数通过最后一个元素
@F[1..$#F,0]是元素1到最后一个元素加上元素0的数组切片