Shell-Script
為什麼 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
這吃掉了文件名的一半。怎麼了?我怎樣才能讓它工作?
不是那個
read
,而是那個echo
。我寫了一個
script.sh
並使用它呼叫它sh script.sh
。在 Debian 和 Ubuntu 中,
sh
isdash
,其中echo
在其參數中評估 C 樣式的反斜杠轉義:$ dash -c 'foo="foo\000bar"; echo "$foo"; printf "%s\n" "$foo"' foo foo\000bar
\000
轉換為 NUL 字節,這顯然結束了輸出的字元串echo
。在這裡引用變數並沒有幫助,因為它只會在命令本身執行之前更改 shell 命令行的處理,而這裡echo
是處理反斜杠的本身。這是一個已知的可移植性問題,在此處進行了更詳細的描述:為什麼 printf 比 echo 更好?
例如,如果給定參數,Bash
echo
會執行反斜杠處理。-e
該問題最初是用bash標記的,所以如果您想使用 Bash 執行腳本,請使用
bash script.sh
,而不是執行它sh script.sh
。