首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在可变长度的直线后面画一条垂直线。

在可变长度的直线后面画一条垂直线。
EN

Unix & Linux用户
提问于 2019-11-20 03:31:28
回答 5查看 2.9K关注 0票数 9

我有一个具有以下格式的文本文件,我想在这些行之后添加一条垂直行,然后是增加的数字:

代码语言:javascript
复制
c4-1 d e c
c d e c
e-2 f g2
e4 f g2
g8-4\( a-5 g f\) e4 c
g'8\( a g f\) e4 c
c-1 r c2
c4 r c2 

我使用以下while-loop实现了行和编号:

代码语言:javascript
复制
#!/bin/bash

while read -r line; do
    if [ -z "$line" ]; then
        echo
        continue
    fi
    n=$((++n)) \
    && grep -vE "^$|^%" <<< "$line" \
    | sed 's/$/\ \|\ \%'$(("$n"))'/'
done < file

得到的输出如下:

代码语言:javascript
复制
c4-1 d e c | %1
c d e c | %2
e-2 f g2 | %3
e4 f g2 | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c | %6
c-1 r c2 | %7
c4 r c2 | %8

现在,我希望添加的内容垂直对齐,并得到如下输出:

代码语言:javascript
复制
c4-1 d e c            | %1
c d e c               | %2
e-2 f g2              | %3
e4 f g2               | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c    | %6
c-1 r c2              | %7
c4 r c2               | %8

这意味着我需要以某种方式获得最长行的行长(在这里:21个字符)和每一行的行长,并添加与空格的差异,我如何实现这一点?

EN

回答 5

Unix & Linux用户

回答已采纳

发布于 2019-11-20 04:17:46

您可以不对齐地打印行,并用column -t和虚拟分隔符字符格式化输出:

代码语言:javascript
复制
#!/bin/bash

while read -r line; do
  if [ -z "$line" ]; then
    echo
    continue
  fi
  printf '%s@| %%%s\n' "$line" "$((++n))"
done < file | column -e -s'@' -t | sed 's/ |/|/'

在这里,我在指示列末尾的@之前添加了一个|作为虚拟字符。末尾的sed命令用于在|之前删除一个额外的空格字符。需要选项-e将空行保留在输出中。

输出:

代码语言:javascript
复制
c4-1 d e c            | %1
c d e c               | %2
e-2 f g2              | %3
e4 f g2               | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c    | %6
c-1 r c2              | %7
c4 r c2               | %8
票数 10
EN

Unix & Linux用户

发布于 2019-11-20 05:33:48

使用awk + GNU wc,假设输入中的所有字符都是单宽的:

代码语言:javascript
复制
$ awk -v f="$(wc -L < ip.txt)" '{printf "%-*s | %%%s\n", f, $0, NR}' ip.txt
c4-1 d e c            | %1
c d e c               | %2
e-2 f g2              | %3
e4 f g2               | %4
g8-4\( a-5 g f\) e4 c | %5
g'8\( a g f\) e4 c    | %6
c-1 r c2              | %7
c4 r c2               | %8
票数 9
EN

Unix & Linux用户

发布于 2019-11-20 15:28:26

平原bash:与bash版本>= 4.0一起工作

代码语言:javascript
复制
#!/bin/bash
mapfile -t lines < file
max=0
for line in "${lines[@]}"; do
    max=$(( ${#line} > max ? ${#line} : max ))
done
for i in "${!lines[@]}"; do
    printf "%-*s | %%%d\n" $max "${lines[i]}" $((i+1))
done

对于较早的bash版本,请用一个while-read循环替换mapfile :这适用于版本3.2。

代码语言:javascript
复制
#!/bin/bash
lines=()
max=0
while IFS= read -r line || [[ -n "line" ]]; do
    lines+=("$line")
    max=$(( ${#line} > max ? ${#line} : max ))
done < file
for i in "${!lines[@]}"; do
    printf "%-*s | %%%d\n" $max "${lines[i]}" $((i+1))
done
票数 4
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/553067

复制
相关文章

相似问题

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