我有一个具有以下格式的文本文件,我想在这些行之后添加一条垂直行,然后是增加的数字:
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实现了行和编号:
#!/bin/bash
while read -r line; do
if [ -z "$line" ]; then
echo
continue
fi
n=$((++n)) \
&& grep -vE "^$|^%" <<< "$line" \
| sed 's/$/\ \|\ \%'$(("$n"))'/'
done < file得到的输出如下:
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现在,我希望添加的内容垂直对齐,并得到如下输出:
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个字符)和每一行的行长,并添加与空格的差异,我如何实现这一点?
发布于 2019-11-20 04:17:46
您可以不对齐地打印行,并用column -t和虚拟分隔符字符格式化输出:
#!/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将空行保留在输出中。
输出:
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发布于 2019-11-20 05:33:48
使用awk + GNU wc,假设输入中的所有字符都是单宽的:
$ 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发布于 2019-11-20 15:28:26
平原bash:与bash版本>= 4.0一起工作
#!/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。
#!/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))
donehttps://unix.stackexchange.com/questions/553067
复制相似问题