45

假设我们有这个数据文件。

john 32 maketing executive
jack 41 chief technical officer
jim  27 developer
dela 33 assistant risk management officer

我想使用打印awk

john maketing executive
jack chief technical officer
jim  developer
dela assistant risk management officer

我知道可以使用for.

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

问题是它很长而且看起来很复杂。

是否有任何其他简短的方法可以打印其余字段

4

7 回答 7

65

将要跳过的字段设置为空白:

awk '{$2 = ""; print $0;}' < file_name

来源:使用 awk 打印从第 n 到最后的所有列

于 2013-08-27T05:23:55.513 回答
9

使用默认 FS 时,使用 GNU awk 可靠地进行 gensub():

$ gawk -v delNr=2 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file
john maketing executive
jack chief technical officer
jim  developer
dela assistant risk management officer

对于其他 awk,您需要使用 match() 和 substr() 而不是 gensub()。请注意,上面的变量 delNr 告诉 awk 您要删除哪个字段:

$ gawk -v delNr=3 '{$0=gensub("^([[:space:]]*([^[:space:]]+[[:space:]]+){"delNr-1"})[^[:space:]]+[[:space:]]*","\\1","")}1' file
john 32 executive
jack 41 technical officer
jim  27
dela 33 risk management officer

不要这样做:

awk '{sub($2 OFS, "")}1'

因为 $2 中的相同文本可能位于 $1 的末尾,和/或 $2 可能包含 RE 元字符,因此您很有可能会以这种方式删除错误的字符串。

不要这样做:

awk '{$2=""}1' file

因为它添加了一个 FS,并将字段之间的所有其他连续空白压缩为一个单独的空白字符。

不要这样做:

awk '{$2="";sub("  "," ")}1' file

因为它有上面提到的空间压缩问题,并且依赖于单个空白的硬编码 FS(虽然是默认的,所以可能不是那么糟糕),但更重要的是,如果在 $1 之前有空格,它将删除其中一个而不是它在 1 美元和 2 美元之间增加的空间。

最后值得一提的是,在最新版本的 gawk 中,有一个名为 patsplit() 的新函数,它的工作方式与 split() 类似,但除了创建字段数组外,它还创建字段之间的空格数组。这意味着您可以在数组中操作字段和 then 之间的空格,因此如果您操作字段,您不必担心 awk 使用 OFS 重新编译记录。然后你只需要从数组中打印你想要的字段。有关更多信息,请参阅http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions中的patsplit() 。

于 2013-08-27T12:11:13.940 回答
5

您可以像这样使用简单的 awk:

awk '{$2=""}1' file

但是,这将在您的输出中有一个额外的 OFS,可以通过这个 awk 避免

awk '{sub($2 OFS, "")}1' file

或者通过使用这个 tr 和 cut 组合:

在 Linux 上:

tr -s ' ' < file | cut -d ' ' -f1,f3-

在 OSX 上:

tr -s ' ' < file | cut -d ' ' -f1 -f3-
于 2013-08-27T05:24:31.470 回答
4

这将删除归档 #2 并清理额外的空间。

awk '{$2="";sub("  "," ")}1' file
于 2013-08-27T05:41:20.900 回答
3

另一种方法是只使用 sed 替换第一个数字和空格匹配:

sed 's|[0-9]\+\s\+||' file

于 2013-08-27T06:41:20.937 回答
0

使用awk它的方法不需要gawk或任何状态突变:

awk '{print $1 " " substr($0, index($0, $3));}' datafile

UPD

更长一点的解决方案,但在 $1 或 $2 包含 $3 时会成立:

awk '{print $1 " " substr($0, length($1 $2) + 1);}' data

如果您有自定义字段分隔符,甚至更强大:

awk '{print $1 " " substr($0, length($1 FS $2 FS) + 1);}' data
于 2020-10-17T06:27:20.817 回答
-1

不要使用更改 $n。如果您想要保留的某些部分有更多空间,它将减少到一个。

于 2021-05-07T18:49:15.473 回答