%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E4%B8%A6%E4%BF%9D%E5%AD%98%E5%9C%A8%E8%AE%8A%E6%95%B8%E4%B8%AD%E6%99%82%E7%84%A1%E6%95%88.png)
如果我在 CLI 中運行:
curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n"
然後,正如預期的那樣,我得到了從頁面到 的經過清理的連結列表STDOUT
,每個連結都在新行上。
但是,當我將其保存到變數並嘗試echo
從 a 中進行操作時script.sh
:
PAGE_LINKS=$(curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n")
echo $PAGE_LINKS
我將所有連結放在一行上,以空格分隔。就好像tr
被忽略了一樣。
我嘗試了多種方法,包括類似的方法
HREFS=$(tr " " "\n" < "{PAGE_LINKS}")
echo $HREFS
但後來我得到了file too long
錯誤。有什麼建議麼?
答案1
根據構造bash
的手冊頁$(command)
:
Bash 透過執行命令並將命令替換替換為命令的標準輸出來執行擴展,並刪除所有尾隨換行符。嵌入的換行符不會被刪除,但它們可能會在分詞過程中被刪除。
所以這tr
不是問題,而是bash
刪除尾隨的換行符,並在分詞期間刪除任何其他換行符。這是記錄的行為。
我相信您在大多數地方都希望這種行為。如果您有一個包含文件名稱清單的文件,則:
for FILENAME in $(cat somefile)
do
...
done
迭代檔案名稱列表。您不希望換行符somefile
弄亂用作文件名的單字列表,甚至可能弄亂您的 for-do-done 循環。
答案2
問題不在於tr
,問題在於如何輸出變數擴展:
echo $PAGE_LINKS
引用變數擴充:
echo "$PAGE_LINKS"
IFS
否則擴充將根據(預設為空格、製表符、換行符)和路徑名擴展(*
, ?
, )的值進行分詞[]
。
在您的情況下,正在發生分詞,並且每個換行符分隔的元素都被單獨獲取,並最終顯示為空格分隔的實體。使用引號將防止分詞(和路徑名擴展),因此整個擴展將被視為單一實體。