내 스크립트가 추가 문자를 생성하는 이유는 무엇입니까?

내 스크립트가 추가 문자를 생성하는 이유는 무엇입니까?

나는 이것이 좋은 일이나 좋은 해결책이 아니라는 것을 알고 있지만 단지 대답하려고 노력하고 있습니다.이것문제, 다음과 같은 문제가 발생했습니다.

목표는 입력 파일을 문자별로 읽고 지정된 범위 내에 있으면 해당 문자를 바꾸는 것입니다.

입력하다:

NNNNN
NNNNN
NNNNN
NNNNN

스크립트:

#!/bin/bash
#set -x

input=~/tmp/in
declare -i count=0
low=$1
high=$2
new_char=$3

while IFS=$'\n' read -r line; do
    while IFS= read -rn1 char; do
        if ((count>=low)) && ((count<=high)); then
            printf '%s' "$new_char"
        else
            printf '%s' "$char"
        fi
        ((count++))
    done <<<"$(printf '%s' "$line")"
    echo
done <"$input"

원하는 출력(실행 시: ) ./script.sh 10 13 P:

NNNNN
NNNNP
PPPNN
NNNNN

실제 출력:

$ ./script.sh 10 13 P
NNNNN
NNNNPP
PPNNN
NNNNN

왜 세 번째 행의 13번째 문자를 교체하는 대신 두 번째 행의 허공에서 새로운 캐릭터를 생성하는 것처럼 보이는지 모르겠습니다. 나는 명령문을 두 번째 while 루프의 시작 부분으로 이동하려고 시도했으며 ((count++))처음부터 시작하려고 시도했으며 |||| 로 보이는 모든 조합을 count=1시도했습니다 . 결과는 다양하지만 모두 두 번째 줄에 추가 문자를 추가하는 것 같습니다.((++count))count=$((count+1))((count+1))

입력 파일의 모든 줄에 후행 공백이 없는지 다시 확인했습니다.

답변1

이 문자열은 끝에 개행 문자를 생성하는 것 같습니다.

차이점을 확인해 보세요.

cat <<<"test"
cat <(printf '%s' "test")

< <(printf '%s' "$line")그러므로 대신 사용해야 합니다 <<<"$(printf '%s' "$line")".

답변2

나는 다음과 같이 쓸 것이다:

while IFS= read -r line; do
    for ((i=0; i<${#line}; i++)); do
        char=${line:i:1}
        ((count++))
        ((low <= count && count <= high)) && char=$new_char
        printf '%s' "$char"
    done
    echo
done <"$input"

관련 정보