當附加到不同檔案時,具有逗號分隔值的 Bash 腳本變數不是逗號分隔的

當附加到不同檔案時,具有逗號分隔值的 Bash 腳本變數不是逗號分隔的

我有一個驗證表條目的 bash 腳本。最終輸出值是 $out,它被插入到 SQL INSERT 語句中,然後附加到 /tmp/crew.txt。雖然 $out 明顯以逗號分隔,但 /tmp/crew.txt 中產生的 INSERT 語句中的值之間沒有逗號。為什麼會發生這種情況以及如何修復它,以便我在 /tmp/crew.txt 中有逗號分隔的值?

#!/bin/bash

out=290,'02:20:00','02:40:00',20.5,NULL

echo "${out:1}"

290,'02:20:00','02:40:00',20.5,NULL


echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
vi /tmp/crew.txt

INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290 '02:20:00' '02:40:00' 20 NULL);

因此 /tmp/crew.txt 中的結果應該是:

INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ( 290,'02:20:00','02:40:00',20,NULL);

答案1

假設:你的IFS變數包含,.該腳本不會更改IFS,因此非預設值必須已在環境中。

這個另一個答案注意到您${out:1}在如下所示的行中未加引號:

echo "foo"${out:1}"bar"

不含引號的變數進行分詞和檔名生成。分詞是透過IFS.未加引號的內容${out:1}被拆分為多個單詞,echo獲取多個參數並列印它們,並用單個空格分隔(因為這就是作用echo,無論IFS)。

如果你用過printf 按照建議,會更容易判斷變數是否被引用:

printf 'INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (%s);\n' "${out:1}"

如果您沒有雙引號變量,printf則會從中取得多個參數${out:1},並且會產生多行。那麼很明顯會發生一些分裂。使用echo它連接它的參數在某種程度上混淆了這個事實。


單獨的問題:

  • 所需的輸出表示您不想要"${out:1}"" $out"有一個前導空格。

  • 要在變數中包含單引號,您應該確保 shell 不會刪除它們。逃離他們(歸功於已經提到的答案) 或用雙引號引起來:

    out="290,'02:20:00','02:40:00',20.5,NULL"
    

答案2

為什麼會出現這種情況以及如何解決

從腳本中刪除回顯的輸出和空白行會得到以下清理後的腳本:

#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt

不過運行該腳本ShellCheck – shell腳本分析工具產生以下錯誤:

$ shellcheck myscript
 
Line 4:
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES ("${out:1}");" >> /tmp/crew.txt
>>                                                                                      ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.

$ 

按照建議刪除引號可以修復該錯誤,所以現在我們有:

#!/bin/bash
out=290,'02:20:00','02:40:00',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> /tmp/crew.txt

然而,運行它仍然沒有給出正確的答案,因為echo "${out:1}"表明單引號'沒有儲存在 中out,並且需要對它們進行轉義:

$ test.sh
90,02:20:00,02:40:00,20.5,NULL
$

解決這個問題可以得到:

#!/bin/bash
out=290,\'02:20:00\',\'02:40:00\',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> test.txt

注意我已將輸出檔名更改為test.txt

測試:

$ test.sh
90,'02:20:00','02:40:00',20.5,NULL
$ cat test.txt
INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (90,'02:20:00','02:40:00',20.5,NULL);
$

所以腳本的最終固定版本是:

#!/bin/bash
out=290,\'02:20:00\',\'02:40:00\',20.5,NULL
echo "${out:1}"
echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> >> /tmp/crew.txt

關於調試損壞的腳本的課程到此結束。

答案3

對我有用的解決方案是回顯以下 INSERT 語句:

echo "INSERT INTO tip_run (date_linkid, start_time, finish_time, weight, note) VALUES (${out:1});" >> /tmp/crew.txt

沒有必要逃避。但不確定原因。

相關內容