我有一个名为replace.run
的脚本,其调用类似于:
$ replace.run 10
此文件包含:
char="pre case\ntext xskey=001 \nREADY\n"
i=2
while [ $i -le $1 ]; do
char="$char pre case\ntext xskey=00$i \nREADY\n"
i=$((i+1))
done
问题在于
$char=pre case\ntext xskey=001 \nREADY\n pre case\ntext xskey=002 \nREADY\n pre case\ntext xskey=003 \nREADY\n pre case\ntext xskey=004 \nREADY\n pre case\ntext xskey=005 \nREADY\n pre case\ntext xskey=006 \nREADY\n pre case\ntext xskey=007 \nREADY\n pre case\ntext xskey=008 \nREADY\n pre case\ntext xskey=009 \nREADY\n pre case\ntext xskey=0010 \nREADY\n
正如您所看到的,READY\n
和pre case
之间有一个空格。这个空间是不需要的。任何帮助摆脱它将是最受欢迎的。
我试过像
echo $char|sed 's/ pre case/pre case/' >char
但这显然是一团糟。
答案 0 :(得分:2)
据我所知,你有这个额外空间的原因是以下含糊不清:
# BUG: this expands $charpre instead of $char
char="$charpre case\ntext xskey=00$i \nREADY\n"
有几种方法可以避免这种情况:
# FIX: use ${} to allow the new "pre" to be immediately after prior content
char="${char}pre case\ntext xskey=00$i \nREADY\n"
...或...
# FIX: use += to append without expanding old content
char+="pre case\ntext xskey=00$i \nREADY\n"
尽管如此,一种完全不同的方法可能更有意义:
lines=( )
for ((i=1; i<=$1; i++)); do
printf -v xskey '%03d' "$i" # format as 0-padded 3-digit value
lines+=( "precase" "text xskey=$xskey" "READY" )
done
printf '%s\n' "${lines[@]}"
这会收集数组中的行,而不是单个字符串,从而为您提供更详细的控制。它还可以确保当您的计数器超过9时,您获得text ksey=010
,而不是text xskey=0010
。
如果你真的想要\n
而不是换行符,你可以通过更改最后一行来进行更改:
# ...if you want to put "\n" strings, not literal newlines, in output:
printf '%s\\n' "${lines[@]}"
答案 1 :(得分:0)
>
重定向到文件。所以你现在有了一个名为char
的文件。
您可以使用命令替换来捕获变量中命令的输出:
char=$(sed 's/pre case/precase/' <<< "$char")
始终记得在变量扩展周围添加双引号"$char"
而不是$char
你根本不需要使用sed:
char="${char/pre case/precase}"
BTW \n
不是bash字符串中的换行符。您可以使用以下c字符串语法$'...'
。哪个将使用C转义序列,例如:
% echo "a\nb"
a\nb
% echo $'a\nb'
a
b