我有一个长这样的文件:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
我想反转顺序,先打印除 $1 以外的所有内容,然后是 $1:
United Arab Emirates AE
如何实现“除了第一个字段之外的所有内容”?
我有一个长这样的文件:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
我想反转顺序,先打印除 $1 以外的所有内容,然后是 $1:
United Arab Emirates AE
如何实现“除了第一个字段之外的所有内容”?
$1=""
留下了一个空格,如Ben Jackson所提到的,因此使用一个 for
循环:
$1=""
留有一个空格,根据Ben Jackson的建议,可以使用一个 for
循环:
awk '{for (i=2; i<=NF; i++) print $i}' filename
如果你的字符串是"one two three",输出结果将为:
two
three
如果你想要结果在一行中显示,可以按照以下方式操作:
awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' filename
这将给你: "two three"。awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}'
。它会打印第2个到最后一个字段,并根据需要添加输出字段分隔符(即,在$2之前除外)。最后一个print语句会在当前行打印结束时添加换行符。如果更改FS/OFS,该命令也可以正常工作(即,它不总是“空格”)。 - Olivier Dulacprintf $i " "
更改为 printf "%s ", $i
。否则,如果您的列中的数据意外包含 printf 格式字符串(如 %s、%i 等),它将会出现错误!是的,这确实发生在我身上 ;) - void256可以使用awk '{first = $1; $1 = ""; print $0, first; }'
来赋值$1
,但会留下一个前导空格。
你还可以通过NF
找到列数并在循环中使用。
从Thyag:为了消除前导空格,在命令的末尾添加sed
:
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
- Thyagawk '/>/ {first = $1; $1=""; gsub(/^ /,""); print $0, first}' somefile
- Salix使用-f 2-
(POSIX)或--complement
(非POSIX)命令来执行cut
命令:
$ echo a b c | cut -f 2- -d ' '
b c
$ 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
echo a b c | cut -d' ' -f 2-
是一种替代方法。 - Luis也许最简洁的方式:
$ 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
说明:
$(NF+1)=$1
:生成“新”的最后一字段。
$1=""
:将原始第一个字段设置为空
sub(FS,"")
:在前两个动作{$(NF+1)=$1;$1=""}
之后,使用sub去除第一个字段分隔符。最后的打印是隐含的。
$1=""
(或$NF=""
或其他任何操作时出现前导或尾随空格的问题。我给你点赞。 - bballdave025awk '{sub($1 FS,"")}7' YourFile
删除第一个字段和分隔符,并打印结果(7
是非零值,因此打印$0)。1
有何不同?我想知道这种模式的用法并希望理解它。谢谢! - shadyabhiawk '{ saved = $1; $1 = ""; print substr($0, 2), saved }'
将第一个字段设置为""
会在$0
的开头留下一个OFS
的副本。假设OFS
只是一个字符(默认情况下,它是一个单独的空格),我们可以使用substr($0, 2)
来删除它。然后,我们附加保存的$1
的副本。
perl -lane 'print join " ",@F[1..$#F,0]' file
这是一个简单的解决方案,其输入/输出分隔符为一个空格,它会产生如下结果:
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
perl -F` ` -lane 'print join " ",@F[1..$#F,0]' file
并且假定输入/输出分隔符是两个空格:
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
-n
循环遍历输入文件的每一行,不会自动打印每一行
- -l
在处理前删除换行符,在处理后添加回来
- -a
自动分割模式 - 将输入行分割成 @F 数组。默认按空格分割
- -F
自动分割修饰符,在此示例中按 ' '(两个空格)分割
- -e
执行以下 Perl 代码
@F
是每行单词的数组,从 0 开始索引
$#F
是 @F
中单词数量
@F[1..$#F]
是元素 1 到最后一个元素的数组切片
@F[1..$#F,0]
是元素 1 到最后一个元素加上元素 0 的数组切片$ awk '{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' file
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
a=$1
:将第一个值保存到临时变量a中。for (i=2; i<=NF; i++) $(i-1)=$i
:将第N个字段的值保存到第(N-1)个字段中。$NF=a
:将第一个值($1
)保存到最后一个字段中。{}1
:为了使awk
执行默认操作:{print $0}
而设置的真条件。这种方法可以应对另一种字段分隔符的情况,结果也是很好的:
$ cat c
AE-United-Arab-Emirates
AG-Antigua-&-Barbuda
AN-Netherlands-Antilles
AS-American-Samoa
BA-Bosnia-and-Herzegovina
BF-Burkina-Faso
BN-Brunei-Darussalam
$ awk 'BEGIN{OFS=FS="-"}{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' c
United-Arab-Emirates-AE
Antigua-&-Barbuda-AG
Netherlands-Antilles-AN
American-Samoa-AS
Bosnia-and-Herzegovina-BA
Burkina-Faso-BF
Brunei-Darussalam-BN
perl -ple 's/^(\S+)\s+(.*)/$2 $1/' file
awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'