如何在Shell脚本中从变量中删除回车符

57

我是 shell 脚本的新手。我正在使用 source 命令导入一个在Windows上创建并含有回车符的文件。当我导入后并追加一些字符时,它总是会跳到行首。

test.dat(末尾含有回车符的文件):

testVar=value123

testScript.sh(上述文件的来源):

source test.dat
echo $testVar got it

我得到的输出是

got it23

如何从变量中删除'\r'


当你在Windows中编写了Linux脚本时,你需要转换整个文件以删除所有回车符才能运行它,否则你会遇到各种问题。尝试替换单个回车可能会解决一些问题,但是其他问题将出现。对我来说,经常出现被截断的行的消息。因此,最好使用类似于dos2unix的程序转换整个文件。 - Dave F
这当然是一个老的,但是这个一行代码也可以胜任。echo ${testVar%'\r'} - AP22
6个回答

92

另一个解决方案使用tr

echo $testVar | tr -d '\r'
cat myscript | tr -d '\r'

-d选项代表删除


这有所帮助,但是对我来说它会移除最后一个单词/字符。 - Clover
@Clover,请您提供一个例子好吗?我认为还有其他东西隐藏着。 - Nik O'Lai

32
你可以按照以下方式使用sed:
MY_NEW_VAR=$(echo $testVar | sed -e 's/\r//g')
echo ${MY_NEW_VAR} got it

顺便提一下,尝试在您的数据文件上执行dos2unix命令。


我已经实现了这个功能,但它会删除所有的“r”,而不仅仅是回车符。 - ffuentes
你确定你保留了 \ 吗? - Xavier S.

25

因为您的源文件使用回车符作为换行符,所以$testVar 的内容可能是这样的:

$ printf '%q\n' "$testVar"
$'value123\r'

(第一行的$是shell提示符;第二行的$来自于%q格式化字符串,表示$''引用。)

要去掉回车符,可以使用shell参数扩展ANSI-C引用(需要Bash):

testVar=${testVar//$'\r'}

应该导致

$ printf '%q\n' "$testVar"
value123

由于某种原因,我需要使用 \n 而不是 \r。 - David Goodwin
@DavidGoodwin 奇怪。 printf'% q \ n' "$testVar"的输出是什么样子的? - Benjamin W.
$'include:(\n .......blah blah .... )\n)' 转换成多行字符串后如下所示:VAR=$(cat < - David Goodwin
@DavidGoodwin 但是你是否有想要删除的回车符? - Benjamin W.
啊啊啊啊啊啊啊 :lightbulb: 等等。谢谢 :) - David Goodwin
谢谢您开启这个主题。我花了一个小时抓狂,因为我正在将一个Windows文件读入Bash变量,结果完全是无意义的。testVar=${testVar//$'\r'}解决了问题。 - user3262284

8

在将脚本文件复制到Linux/Unix后,请在脚本文件上使用此命令。

perl -pi -e 's/\r//' scriptfilename

非常感谢perl。我无法下载dos2unixtr也无法使用等等!非常感谢! - Mrigank Pawagi
1
我使用了 perl -p -e 's/\r\n$//' 命令来仅从输入的末尾删除 \r\n - Gordon Bean

6

将文本传输到 sed -e 's/[\r\n]//g',以从每个文本行中删除回车符 (\r) 和换行符 (\n)。


4
你不能像那样使用sed来删除\n。请参考http://sed.sourceforge.net/sedfaq5.html#s5.10。 - Bryan

5

如果要纯shell解决方案而不调用外部程序:

NL=$'\n'    # define a variable to reference 'newline'

testVar=${testVar%$NL}    # removes trailing 'NL' from string

问题在于回车符,而不是换行符。 - Benjamin W.
所以 NL=$'\n' 和 NR=$'\r',并且替换两者,如果没有找到条件,则不会发生任何事情。 - user176495

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接