次の形式のテキストファイルがありますが、行の後に垂直線を追加して数字を追加したいと思います。
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文字)と空白が追加された各行の行の長さとの間の違いを何らかの形で取得する必要があることを意味します。どうすればいいですか?
答え1
ソートされていない行を印刷し、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
答え2
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
答え3
汎用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バージョンの場合は、マップファイルを読み込みながらループに置き換えます。これはバージョン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
答え4
記録のために:(非常に遅いが最初に試してみることです。wc -L
)
確かに@Freddyの答えを使用しますcolumn
!
#!/bin/bash
file="$1"
ll=$(wc -L < "$file")
while read -r line; do
if [ -z "$line" ]; then
echo
continue
fi
sl=$(wc -L <<< "$line")
if [ "$ll" = "$sl" ]; then
as=$(echo "$ll - $sl" | bc)
else
as=$(echo "$ll - $sl + 1" | bc)
fi
space=$(printf '\ %.0s' $(seq "$as") )
n=$((++n)) \
&& grep -vE "^$|^%" <<< "$line" \
| sed "s/$/$space\ \|\ \%$(printf "%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