Bash - draw a vertical line behind lines with variable length
You could print the lines without alignment and format the output with column -t
and a dummy delimiter character:
#!/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/ |/|/'
Here, I added a @
as dummy character before the |
indicating the end of the column.
The sed
command at the end is used to remove one additional space character before the |
. Option -e
is needed to keep empty lines in the output.
Output:
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
Using awk
+ GNU wc
assuming all characters in the input are single-width:
$ 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
Plain bash: works with bash version >= 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
For older bash versions, replace mapfile with a while-read loop: this works with version 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))
done