使用 awk 或 sed 打印从第 n 个到最后一个的所有列

using awk or sed to print all columns from the n-th to the last

这不是 another question 的副本。 之前在 Whosebug 上发布的所有 questions/solutions 都遇到了同样的问题:额外的 space 被替换为单个 space。

示例 (1.txt)

filename Nospaces
filename One space
filename Two  spaces
filename Three   spaces

结果:

awk '{="";[=11=]=[=11=];=}1' 1.txt
One space
Two spaces
Three spaces

awk '{=""; print substr([=11=],2)}' 1.txt
One space
Two spaces
Three spaces

使用cut:

cut -d' ' -f2- a.txt

打印从第二列到最后一列的所有列并保留空格。

如果您将字段定义为任意数量的 非 space 字符后跟任意数量的 space 个字符,那么你可以像这样删除第一个 N

$ sed -E 's/([^[:space:]]+[[:space:]]*){1}//' file
Nospaces
One space
Two  spaces
Three   spaces

{1} 更改为 {N},其中 N 是要删除的字段数。如果您只想从一开始就删除 1 个字段,那么您可以完全删除 {1}(以及用于创建组的括号):

sed -E 's/[^[:space:]]+[[:space:]]*//' file

某些版本的 sed(例如 GNU sed)允许您使用 shorthand:

sed -E 's/(\S+\s*){1}//' file

如果行首可能有一些白色space,您可以在花样的开头添加一个\s*(或[[:space:]]*),在行的外面群组:

sed -E 's/\s*(\S+\s*){1}//' file

使用 awk 的问题在于,每当您触摸给定记录上的任何字段时,整个记录都会重新格式化,导致每个字段由 OFS(输出字段分隔符)分隔,这是默认为单个 space。如果需要,您可以将 awk 与 sub 一起使用,但由于这是一个简单的替代,sed 是完成这项工作的正确工具。

-F 选项指定 IFS 以避免 awk

省略多个 space
awk -F "[ ]" '{="";[=10=]=[=10=];=}1' 1.txt
awk -F "[ ]" '{=""; print substr([=10=],2)}' 1.txt

要在 awk 中保留空格,您必须使用正则表达式替换或使用子字符串。一旦您开始修改单个字段,awk 就必须使用定义的(或隐式的)OFS 重新计算 $0。

参考 Tom 的 sed 回答:

awk '{sub(/^([^[:blank:]]+[[:blank:]]+){1}/, "", [=10=]); print}' 1.txt

awk 中的工作代码,无前导 space,支持列中的多个 space 并从第 n 列打印:

awk '{ print substr([=10=], index([=10=],$column_id)) }' 1.txt