首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编写bash脚本来填充文本表的空字段

如何编写bash脚本来填充文本表的空字段
EN

Stack Overflow用户
提问于 2020-12-11 06:04:10
回答 1查看 89关注 0票数 0

我有一个bash脚本,它生成一个表作为输出,如下所示:

代码语言:javascript
运行
复制
Name                 IP Address        IPv6 Address                     Address Source   Connection Type
Inferno              192.168.0.12      N/A                              DHCP             Ethernet 
VirgilioMarone       192.168.0.10      N/A                              DHCP             Ethernet 
RE305                192.168.0.2       N/A                              DHCP             Wi-Fi 
Google-Nest-Hub      192.168.0.100     N/A                              DHCP             Wi-Fi 
iPaddiG              192.168.0.216     N/A                              DHCP             Wi-Fi 
*                                      N/A                              DHCP             Wi-Fi 
Alighieri            192.168.0.13      N/A                              DHCP             Wi-FI

我需要确定一个算法,该算法接收上表并将"-“放在字段为null的地方,如下所示(我不会复制其他行,只是为了简化文本):

代码语言:javascript
运行
复制
Name              IP Address        IPv6 Address                     Address Source   Connection Type
   *              -                 N/A                              DHCP             Wi-Fi 5GHz

附注:文本之间没有制表符;只有空格。

EN

回答 1

Stack Overflow用户

发布于 2020-12-12 04:27:48

我将使用第一行来获取每列的预期大小。

代码语言:javascript
运行
复制
head -1 /path/to/file |
  grep -oE '[^ ]([^ ]| [^ ])* *  ' |
  awk '{print length($0)}'

  • head -1保留第一行only
  • grep -oE '[^ ]([^ ]| [^ ])* * '捕获所有以非空格字符[^ ]开头的字符串,后跟不包含两个连续空格的空格序列([^ ]| [^ ])*,并以至少包含两个空格的空格序列结束*;注意正则表达式中的确切字符,否则它将不会执行

,而只是显示每个序列的长度

请注意,缺少最后一列,因为它不是以2+空格结尾。这是一件好事,因为我假设最后一列不应该被限制为固定的宽度。

对于您的示例,它输出:

代码语言:javascript
运行
复制
21
18
33
17

一旦你有了这个列表,你就可以将它存储到一个数组中,例如:

代码语言:javascript
运行
复制
mapfile -t widths < <(head -1 /path/to/file |
  grep -oE '[^ ]([^ ]| [^ ])* *  ' |
  awk '{print length($0)}')

然后,您可以读取每一行,并使用每列的固定宽度将其拆分:

代码语言:javascript
运行
复制
while IFS= read -r line || [[ -n "$line" ]]; do
  t=0;
  for x in "${widths[@]}"; do
    s=${line:$t:$x};
    if [[ "$s" =~ ^\ *$ ]]; then
      printf %s "${s/ /-}";
    else
      printf -- %s "$s";
    fi;
    ((t+=x));
  done;
  s=${line:$t};
  if [ -z "$s" ]; then
    printf -- -\\n;
  else
    if [[ "$s" =~ ^\ *$ ]]; then
      printf %s\\n "${s/ /-}";
    else
      printf -- %s\\n "$s";
    fi;
 fi;
done < /path/to/file

  • while IFS= read -r line || [[ -n "$line" ]]; do ... done < /path/to/file读取$line变量中的每一行;使用-r选项读取以便不解释转义序列,并设置IFS=以便不修剪前导和尾随空格,这一点非常重要;|| [[ -n "$line" ]]奖励是一个技巧,它修复了read的限制,如果文件的最后一行不以换行符结束,则返回false。character
  • t是到目前为止在line
  • for x in "${widths[@]}"; do ... done循环中通过widths数组读取的字符总数计算得到的t从索引t+x中提取字符,换句话说,它从行中提取一列,保留尾随空格字符,这就是魔术发生的地方。因为一旦有了它,你就需要won
  • if [[ "$s" =~ ^\ *$ ]]; then printf %s "${s/ /-}"; else printf -- %s "$s"; fi;检查列是否完全为空,在这种情况下,它调用printf %s "${s/ /-}"输出第一个字符被连字符替换的字符串,同时保持字段宽度不变(你可以对printf -- "%-${x}s" -做同样的事情),否则它会按printf -- %s "$s"打印字符串,请确保使用--,否则,如果字符串"$s"以hypen
  • ((t+=x))开头,将变量t推进到下一列,以便下一列从正确的索引
  • 开始,然后s=${line:$t}获取从索引t开始直到行尾的最后一列,即如果没有固定宽度的
  • ,则最后一列的打印与其他列基本相同,除非我们处理空列的情况(这不会发生在以前的列上),并且我们以\\n结束输出,以便输出换行符

如果一切顺利,它应该会显示:

代码语言:javascript
运行
复制
Name                 IP Address        IPv6 Address                     Address Source   Connection Type
Inferno              192.168.0.12      N/A                              DHCP             Ethernet
VirgilioMarone       192.168.0.10      N/A                              DHCP             Ethernet
RE305                192.168.0.2       N/A                              DHCP             Wi-Fi
Google-Nest-Hub      192.168.0.100     N/A                              DHCP             Wi-Fi
iPaddiG              192.168.0.216     N/A                              DHCP             Wi-Fi
*                    -                 N/A                              DHCP             Wi-Fi
Alighieri            192.168.0.13      N/A                              DHCP             Wi-FI
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65242985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档