如何在Bash中当文本第二列内容变化时打印分隔线
Bash实现:按服务分组插入分隔线整理Ansible状态输出
需求说明
我通过Ansible playbook查询服务状态得到以下原始数据:
host1 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:02 HKT; 2 days ago host2 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:01 HKT; 2 days ago host3 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:01 HKT; 2 days ago host1 : Broker : Active: active (running) since Wed 2023-02-15 14:06:53 HKT; 1 day 23h ago host2 : Broker : Active: active (running) since Wed 2023-02-15 14:07:33 HKT; 1 day 23h ago host3 : Broker : Active: active (running) since Wed 2023-02-15 14:07:45 HKT; 1 day 23h ago host4 : Broker : Active: active (running) since Wed 2023-02-15 14:07:52 HKT; 1 day 23h ago host2 : SchemaRegistry : Active: active (running) since Wed 2023-02-15 14:13:41 HKT; 1 day 23h ago host3 : SchemaRegistry : Active: active (running) since Wed 2023-02-15 14:15:04 HKT; 1 day 23h ago host4 : Connect : Active: active (running) since Wed 2023-02-15 14:26:51 HKT; 1 day 23h ago host1 : ControlCenter : Active: active (running) since Wed 2023-02-15 13:45:09 HKT; 2 days ago host5 : KSQL : Active: active (running) since Wed 2023-02-15 14:20:28 HKT; 1 day 23h ago host6 : KSQL : Active: active (running) since Wed 2023-02-15 14:20:28 HKT; 1 day 23h ago host5 : RestProxy : Active: active (running) since Fri 2023-01-27 22:38:59 HKT; 2 weeks 6 days ago host6 : RestProxy : Active: active (running) since Wed 2023-02-15 14:31:59 HKT; 1 day 23h ago
需要将其整理为按服务分组、每组前后插入分隔线的格式,效果如下:
------------------------------------------------------------------------------------------------- host1 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:02 HKT; 2 days ago host2 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:01 HKT; 2 days ago host3 : zookeeper : Active: active (running) since Wed 2023-02-15 13:57:01 HKT; 2 days ago ------------------------------------------------------------------------------------------------- host1 : Broker : Active: active (running) since Wed 2023-02-15 14:06:53 HKT; 1 day 23h ago host2 : Broker : Active: active (running) since Wed 2023-02-15 14:07:33 HKT; 1 day 23h ago host3 : Broker : Active: active (running) since Wed 2023-02-15 14:07:45 HKT; 1 day 23h ago host4 : Broker : Active: active (running) since Wed 2023-02-15 14:07:52 HKT; 1 day 23h ago ------------------------------------------------------------------------------------------------- host2 : SchemaRegistry : Active: active (running) since Wed 2023-02-15 14:13:41 HKT; 1 day 23h ago host3 : SchemaRegistry : Active: active (running) since Wed 2023-02-15 14:15:04 HKT; 1 day 23h ago ------------------------------------------------------------------------------------------------- host4 : Connect : Active: active (running) since Wed 2023-02-15 14:26:51 HKT; 1 day 23h ago ------------------------------------------------------------------------------------------------- host1 : ControlCenter : Active: active (running) since Wed 2023-02-15 13:45:09 HKT; 2 days ago ------------------------------------------------------------------------------------------------- host5 : KSQL : Active: active (running) since Wed 2023-02-15 14:20:28 HKT; 1 day 23h ago host6 : KSQL : Active: active (running) since Wed 2023-02-15 14:20:28 HKT; 1 day 23h ago ------------------------------------------------------------------------------------------------- host5 : RestProxy : Active: active (running) since Fri 2023-01-27 22:38:59 HKT; 2 weeks 6 days ago host6 : RestProxy : Active: active (running) since Wed 2023-02-15 14:31:59 HKT; 1 day 23h ago -------------------------------------------------------------------------------------------------
核心需求:每行第二列(服务名称)变化时,自动插入分隔线。
Bash实现方案
可以使用awk工具完成文本处理,以下是具体脚本:
awk -F': ' ' BEGIN { sep = "-------------------------------------------------------------------------------------------------" print sep } { current_service = $2 gsub(/^[[:space:]]+|[[:space:]]+$/, "", current_service) # 去除服务名前后空格 if (NR > 1 && current_service != prev_service) { print sep } print $0 prev_service = current_service } END { print sep } ' service_status.txt
脚本说明
- 分隔符设置:用
-F': '指定分隔符为:,这样每行被分割为多个字段,第二字段$2就是服务名称。 - 初始化:
BEGIN块先打印第一条分隔线。 - 逐行处理:
- 提取当前行的服务名称,并去除前后多余空格。
- 如果不是第一行且当前服务名和上一行服务名不同,打印分隔线。
- 打印当前行内容。
- 更新上一行服务名为当前服务名。
- 收尾:
END块打印最后一条分隔线。
使用方法
- 将Ansible输出的原始状态数据保存到文件(比如
service_status.txt)。 - 运行上述脚本,即可得到分组带分隔线的格式化输出。
- 也可以直接通过管道处理Ansible的实时输出,比如:
ansible-playbook your_playbook.yml | awk -F': ' ' BEGIN { sep = "-------------------------------------------------------------------------------------------------" print sep } { current_service = $2 gsub(/^[[:space:]]+|[[:space:]]+$/, "", current_service) if (NR > 1 && current_service != prev_service && $2 != "") { # 过滤空行或非状态行 print sep } if ($2 != "") print $0 # 只输出有效状态行 prev_service = current_service } END { print sep } '
内容的提问来源于stack exchange,提问作者swapnil kambli
相关产品推荐
相关产品推荐

