我知道这不是一件好事和/或一个好的解决方案,但我只是在尝试回答这问题,我遇到了以下问题。
目标是逐个字符读取输入文件,如果该字符在指定范围内,则替换它。
输入:
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 个角色。我尝试将((count++))
语句移动到第二个 while 循环的开头,我尝试从 开始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"