Shell-Script

為什麼 read -r 吃文本?

  • March 29, 2017

我有一個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

這吃掉了文件名的一半。怎麼了?我怎樣才能讓它工作?

不是那個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 更好?

例如,如果給定參數,Bashecho會執行反斜杠處理。-e

該問題最初是用bash標記的,所以如果您想使用 Bash 執行腳本,請使用bash script.sh,而不是執行它sh script.sh

引用自:https://unix.stackexchange.com/questions/354599