다음 형식의 텍스트 파일이 있는데 줄 뒤에 수직선을 추가하고 숫자를 추가하고 싶습니다.
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