2011-06-23 83 views
0

我正在嘗試執行以下操作。我想讓用戶爲我提供一個包含ID列表的文件。它看起來像這樣:使用sed替換模板文件中包含引號的變量的文本

41aeb908-dfc7-4cf8-8285-31ca184dc1c5 
da877ffa-49bc-4f07-b692-4873870fcb37 
a555cdd0-e100-42cb-a355-140de7958b36 

該文件可能有10或100這些行在那裏。它會有所不同。然後我想用SQLPlus將它們提供給SQL查詢。爲了做到這一點,我需要在每一行中加上引號,並在每行之後加逗號。

echo "Formatting XIDs for query..." 
formattedtxs=`sed -e "s/^/'/g" -e "s/$/'/g" -e "s/$/,/g" $1` 

$ 1將具有要處理的文件名。然後我有一個文件,我將把這些文件放入。

select distinct tt.transaction_id||','||tt.entity_id||','||cm.user_id 
from transaction_tracker tt, course_membership cm 
tt.entity_id = cm.course_id and 
tt.transaction_id IN (XXXXXXXX); 

我的想法是把那些XXXX作爲我的模板放在那裏,讓sed找到並用我的文本替換它。

echo "Substituting XIDs into query template..." 
sed "s/XXXXXXXX/$formattedtxs/" <query.template>query.tmp 

它不起作用,因爲它給出錯誤未終止's'命令。我猜這是因爲我的formattedtxs變量本身有單引號。有任何想法嗎?第一個sed命令的結果是這樣的

'41aeb908-dfc7-4cf8-8285-31ca184dc1c5', 'da877ffa-49bc-4f07-b692-4873870fcb37', 'a555cdd0-e100-42cb-a355-140de7958b36', '2b7794f5-9811-4cf3-bd42-1d459d8cb6eb', '6133179e-4e4c-4917-a132-1ee03ab88465', '81343735-e943-4084-ab9f-86f8b5aedfa9', 

如果你能擺脫最後一個逗號,獎勵點數。

回答

2

保存此到文件 「mksql.bash」 左右...

sed "s/REPLACEME/$(sed "s/.*/'&'/" | paste -s -d, -)/" < template_file.txt 

,並用它喜歡:

bash mksql.bash < your_id_file 

會產生

select distinct tt.transaction_id||','||tt.entity_id||','||cm.user_id 
from transaction_tracker tt, course_membership cm 
tt.entity_id = cm.course_id and 
tt.transaction_id IN ('41aeb908-dfc7-4cf8-8285-31ca184dc1c5','da877ffa-49bc-4f07-b692-4873870fcb37','a555cdd0-e100-42cb-a355-140de7958b36'); 

的「template_file。 txt「包含你的sql模板:

select distinct tt.transaction_id||','||tt.entity_id||','||cm.user_id 
from transaction_tracker tt, course_membership cm 
tt.entity_id = cm.course_id and 
tt.transaction_id IN (REPLACEME); 

我已經取代了很多XX ..X與 「REPLACEME」 因爲我很懶計數XES

順便說一句,歡迎SO ... :)

+0

+10 :)爲令人難以置信的命令替換 - sed內部sed – kobame

+0

真棒解決方案。我在他們中的兩個之間被撕裂。我有一個理由今天進行測試。 – Stefano

3

假設你不結婚sed和可以使用一個簡單的bash腳本,你可以這樣做:

cat $1 | while read line; do echo -n "'$line',"; done | sed 's/,$//'; echo 

其中$ 1是要讀取的文件。

+0

[無用的'cat'](http://partmaps.org/era/unix/award.html)檢測到:使用'done <$ 1'代替。 – l0b0

0

您可以用很少照顧一個sed命令做到這一點:

sed -e '1i\ 
     select distinct tt.transaction_id||','||tt.entity_id||','||cm.user_id\ 
     from transaction_tracker tt, course_membership cm\ 
     tt.entity_id = cm.course_id and\ 
     tt.transaction_id IN (' \ 
    -e "s/.*/'&',/" \ 
    -e "\$a\ 
     'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')" > query.tmp 

有很多X的的進入顯然不是一個有效的GUID,因此將不匹配,反而會(UUID?)中和上一個有效GUID的尾隨逗號。

如果您希望材料來自模板文件,則可以使用'-e "1r $template_file"'而不是insert命令。您可以使用'-e "\$r $trailing_file"'添加尾部素材。等

這裏的一個很大一部分技巧是處理與SQL引用交互的shell引用。跟蹤哪個流程可以看到什麼很難,但非常重要。

+0

整個壞處是shell引用與SQL引用交互。我喜歡這個解決方案,因爲它讓我保持sed。謝謝! – Stefano

0

純擊:

declare -a a=($(cat $1)) # IDs into an array 
result="${a[*]}"    # array to string, blank as separator 
result=\'${result// /\', \'}\' # substitute blanks with ', '/add first, last ' 

echo -e "${result}" 

這給:

'41aeb908-dfc7-4cf8-8285-31ca184dc1c5', 'da877ffa-49bc-4f07-b692-4873870fcb37', 'a555cdd0-e100-42cb-a355-140de7958b36'