printf 是 "eating" 的反斜杠。如何保存它们?
printf is "eating" the backslashes. How to preserve them?
我正在尝试制作一个小巧的 POSIX 兼容的类似 sed 的函数。但是我注意到下面的代码是 "eating" 反斜杠。
input.txt
为 mysed ./input.txt "TEST2" "TEST2=\"two\""
调用:
TEST1="\_PR.CP%02d"
TEST2="one"
TEST3="\_PR.P%03d"
预计:
TEST1="\_PR.CP%02d"
TEST2="two"
TEST3="\_PR.P%03d"
收到:
TEST1="\_PR.CP%02d"
TEST2="two"
TEST3="\_PR.P%03d"
如何修改下面的代码来保留所有的反斜杠?也许可以用更好的东西替换自定义 printf '%b\n'
格式?
#!/bin/sh
# Replaces the lines containing the text '' of a file '' with a line ''.
mysed () {
if [ -f "" ] ; then
mysed_tmp="./.mysed"
rm -f $mysed_tmp
while IFS= read -r line
do
case $line in
*""*)
if [ ! -z "" ] ; then
printf '%b\n' "" >> $mysed_tmp
fi
;;
*)
printf '%b\n' "$line" >> $mysed_tmp
;;
esac
done < ""
mv $mysed_tmp
return 0
else
return 1
fi
}
echo "TEST1=\"\\_PR.CP%02d\"" > input.txt
echo "TEST2=\"one\"" >> input.txt
echo "TEST3=\"\\_PR.P%03d\"" >> input.txt
mysed ./input.txt "TEST2" "TEST2=\"two\""
cat ./input.txt
编辑: 将 '%b\n'
替换为 '%s\n'
,现在一切正常。
看:
$ x="TEST2=\"two\""; printf '%s\n' "$x"
TEST2="two"
$ x='TEST2=\"two\"'; printf '%s\n' "$x"
TEST2=\"two\"
$ TEST1="\_PR.CP%02d"; printf '%s\n' "$TEST1"
\_PR.CP%02d
$ TEST1='\_PR.CP%02d'; printf '%s\n' "$TEST1"
\_PR.CP%02d
希望这会让事情变得更清楚:
$ foo() { printf '%%b:<%b>\n%%s:<%s>\n---\n' "" ""; }
$ foo "TEST2=\"two\""
%b:<TEST2= wo\>
%s:<TEST2=\two\>
---
$ foo 'TEST2=\"two\"'
%b:<TEST2=\"two\">
%s:<TEST2=\"two\">
---
所以:
- 如果您不想在定义字符串时被 shell 去除反斜杠,那么不要让 shell 解释它们 - 使用
'
而不是 "
.
- 如果您不希望在打印字符串时 printf 去除反斜杠,则不要告诉 printf 解释它们 - 使用
%s
而不是 %b
.
我正在尝试制作一个小巧的 POSIX 兼容的类似 sed 的函数。但是我注意到下面的代码是 "eating" 反斜杠。
input.txt
为 mysed ./input.txt "TEST2" "TEST2=\"two\""
调用:
TEST1="\_PR.CP%02d"
TEST2="one"
TEST3="\_PR.P%03d"
预计:
TEST1="\_PR.CP%02d"
TEST2="two"
TEST3="\_PR.P%03d"
收到:
TEST1="\_PR.CP%02d"
TEST2="two"
TEST3="\_PR.P%03d"
如何修改下面的代码来保留所有的反斜杠?也许可以用更好的东西替换自定义 printf '%b\n'
格式?
#!/bin/sh
# Replaces the lines containing the text '' of a file '' with a line ''.
mysed () {
if [ -f "" ] ; then
mysed_tmp="./.mysed"
rm -f $mysed_tmp
while IFS= read -r line
do
case $line in
*""*)
if [ ! -z "" ] ; then
printf '%b\n' "" >> $mysed_tmp
fi
;;
*)
printf '%b\n' "$line" >> $mysed_tmp
;;
esac
done < ""
mv $mysed_tmp
return 0
else
return 1
fi
}
echo "TEST1=\"\\_PR.CP%02d\"" > input.txt
echo "TEST2=\"one\"" >> input.txt
echo "TEST3=\"\\_PR.P%03d\"" >> input.txt
mysed ./input.txt "TEST2" "TEST2=\"two\""
cat ./input.txt
编辑: 将 '%b\n'
替换为 '%s\n'
,现在一切正常。
看:
$ x="TEST2=\"two\""; printf '%s\n' "$x"
TEST2="two"
$ x='TEST2=\"two\"'; printf '%s\n' "$x"
TEST2=\"two\"
$ TEST1="\_PR.CP%02d"; printf '%s\n' "$TEST1"
\_PR.CP%02d
$ TEST1='\_PR.CP%02d'; printf '%s\n' "$TEST1"
\_PR.CP%02d
希望这会让事情变得更清楚:
$ foo() { printf '%%b:<%b>\n%%s:<%s>\n---\n' "" ""; }
$ foo "TEST2=\"two\""
%b:<TEST2= wo\>
%s:<TEST2=\two\>
---
$ foo 'TEST2=\"two\"'
%b:<TEST2=\"two\">
%s:<TEST2=\"two\">
---
所以:
- 如果您不想在定义字符串时被 shell 去除反斜杠,那么不要让 shell 解释它们 - 使用
'
而不是"
. - 如果您不希望在打印字符串时 printf 去除反斜杠,则不要告诉 printf 解释它们 - 使用
%s
而不是%b
.