为什么 read -r 会吃掉文本?

为什么 read -r 会吃掉文本?

我有一个names.txt文件,其顶行文本是

51 Pipe-line\Closed3\00001011_-_Portfolio\UW\Old\NID50_Future_022814.xlsx

我想写新的文件名替换\/

我编写了一个script.sh并使用调用它sh script.sh。我的第一次尝试...


while read one two three; do

  new=$(echo $two|tr '\\' '/')
  echo $one
  echo $two
  echo $three
  echo $new

done < ./names.txt

51
Pipe-lineClosed300001011_-_PortfolioUWOldNID50_Future_022814.xlsx

Pipe-lineClosed300001011_-_PortfolioUWOldNID50_Future_022814.xlsx

/把炭吃了。我发现通过了-r遗嘱显示,/所以我的下一次尝试是

 while read -r one two three; do

  new=$(echo $two|tr '\\' '/')
  echo $one
  echo $two
  echo $three
  echo $new

done < ./names.txt

51
Pipe-line\Closed3

Pipe-line/Closed3

这会占用文件名的一半。怎么了?我该如何让它发挥作用?

答案1

不是那个read,而是那个echo

我编写了一个script.sh并使用调用它sh script.sh

在 Debian 和 Ubuntu 中,shis dash,其中echo计算其参数中的 C 风格反斜杠转义符:

$ dash -c 'foo="foo\000bar"; echo "$foo"; printf "%s\n" "$foo"' 
foo
foo\000bar

转换\000为 NUL 字节,这显然结束了输出的字符串echo。引用变量在这里没有帮助,因为它只会在命令本身运行之前更改 shell 命令行的处理,而这里是它echo本身处理反斜杠。

这是一个已知的可移植性问题,此处有更详细的描述:为什么 printf 比 echo 更好?

例如,echo如果给定参数,Bash 就会进行反斜杠处理-e

该问题最初标记为,因此如果您想使用 Bash 运行脚本,请使用 运行bash script.sh,而不是sh script.sh

答案2

这可以使用 sed 以更简单、更可靠的方式完成:

sed -i 's|\\|/|g' myfile

给出:

cat myfile 51 Pipe-line/Closed3/00001011_-_Portfolio/UW/Old/NID50_Future_022814.xls

编辑

根据您的评论,这就是我实现这一目标的方式:

for i in $(cat test | awk '{print $2}')
do
  mv $i `sed 's|\\|/|g' <<< $i`
done

答案3

只需这样就足够了:

tr '\\' / < names.txt

相关内容