You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用awk保留第一个字段的前置空格并输出指定字段

保留字段原始前置空格输出指定字段的解决方案

问题描述

有如下格式的输入文本:

aaaaaa bbbb     cccccc
     dddddddddddddd ee  fff
  gggggggg hhh   iiiii

需要仅输出第1和第3字段,同时保留第一个字段的原始前置空格,期望输出:

aaaaaa cccccc
     dddddddddddddd fff
  gggggggg iiiii

使用简单的print($1,$3)会丢失前置空格:

aaaaaa cccccc
ddddddddddddddd fff
gggggggg iiiii

尝试$1=sprintf("%20s",$1)会导致第一个字段右对齐到指定列,不符合需求:

aaaaaa cccccc
      dddddddddddddd fff
            gggggggg iiiii

解决方案

方法1:利用awk的match函数提取前置空格与字段内容

核心思路是先匹配每行开头的所有空白字符,再提取第一个非空白字段和第三个字段,最后拼接输出:

match($0, /^[[:space:]]+/, pre) {
    print pre[0] $1, $3
}

解释:

  • match($0, /^[[:space:]]+/, pre) 匹配行首所有空白字符,存入数组pre
  • pre[0] 就是行首的原始前置空格,再拼接$1和$3即可保留原始格式

方法2:拆分行首空白与内容,再重组

如果你的awk版本不支持第三个参数(存储匹配结果的数组),可以用以下写法:

{
    space = substr($0, 1, length($0) - length(ltrim($0)))
    print space $1, $3
}
function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s }

解释:

  • 自定义ltrim函数去除字符串开头的空白
  • 通过计算原行长度减去去空白后的长度,得到行首空白的长度,再用substr提取原始空格
  • 最后拼接空格、$1和$3输出

方法3:使用gensub直接替换不需要的字段

另一种思路是直接把第二个字段(包括其前后的空白)替换为空,只保留行首空格、第一个字段和第三个字段:

{ print gensub(/^([[:space:]]+\S+)\s+\S+\s+(.*)/, "\\1 \\2", 1) }

解释:

  • 正则表达式^([[:space:]]+\S+)\s+\S+\s+(.*)捕获三个部分:行首空格+第一个字段、第二个字段、第三个字段及后续内容
  • 替换为\\1 \\2,即保留第一部分和第三部分,中间用空格分隔,刚好符合需求

内容的提问来源于stack exchange,提问作者Philippe le peuch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:32:41