所以我有一個由各種腳本決議的組態檔,因此格式不能更改,盡管只要嚴格遵循格式,內容就可以。默認情況下,此檔案包含字串,例如
multiconfig:nmb-devel:nmb-trs-devel
multiconfig:nmb-deploy:nmb-trs-deploy
multiconfig:nmb-deploy:nmb-trs-deploy
multiconfig:ijk-devel:ijk-trs-devel
multiconfig:ijk-deploy:ijk-trs-deploy
multiconfig:ijk-deploy:ijk-trs-deploy
multiconfig:qrs-devel:qrs-trs-devel
multiconfig:qrs-deploy:qrs-trs-deploy
multiconfig:qrs-deploy:qrs-trs-deploy
目前,我有一個腳本可以將這些配置(multiconfig:...)決議成一個陣列,以及一個配置陣列來替換這些原始配置。例如
忽略下面的尾部操作,ACTUAL conf.txt 包含另一個要跳過的匹配項,這是成功完成的。
TARGETS="multiconfig:new-devel:new-trs-devel multiconfig:newer-devel:newer-trs-devel multiconfig:newest-devel:newest-trs-devel"
NEW_TARGETS_ARR=( $TARGETS )
OLD_TARGETS_ARR=($(sed -n '/multiconfig/p' conf.txt | tail -n 2 | awk '!seen[$0] '))
注意: 不是有問題的 sed 操作
這些作業正常,并產生正確的陣列,例如:
NEW_TARGETS_ARR:multiconfig:new-devel:new-trs-devel,multiconfig:newer-devel:newer-trs-devel,multiconfig:newest-devel:newest-trs-devel
OLD_TARGETS_ARR: multiconfig:nmb-devel:nmb-trs-devel, multiconfig:nmb-deploy:nmb-trs-deploy, multiconfig:nmb-deploy:nmb-trs-deploy , multiconfig:ijk-devel:ijk-trs-devel, multiconfig:ijk-deploy:ijk-trs-deploy, multiconfig:ijk-deploy:ijk-trs-deploy , multiconfig:qrs-devel:qrs-trs-devel, multiconfig:qrs-deploy:qrs-trs-deploy, multiconfig: qrs-部署:qrs-trs-部署
我的目標是用新配置替換舊配置。
我現在這樣做的方法是回圈遍歷 OLD_TARGETS_ARR 并將每個 OLD_TARGETS_ARR[index] 替換為 NEW_TARGETS_ARR[index] ,如下所示:
for i in ${!OLD_TARGETS_ARR[@]}
do
if [ "${NEW_TARGETS_ARR[$i]}" = "" ]; then
NEW_TARGETS_ARR[$i]="[EMPTY]"
fi
echo $i
echo "OLD TARGET $i: ${OLD_TARGETS_ARR[$i]}"
echo "NEW TARGET $i: ${NEW_TARGETS_ARR[$i]}"
echo "sed -i \"s/${OLD_TARGETS_ARR[$i]}/${NEW_TARGETS_ARR[$i]}/g\" conf.txt"
sed -i "s/${OLD_TARGETS_ARR[$i]}/${NEW_TARGETS_ARR[$i]}/g" conf.txt
done
現在,理論上這應該(或我想要的)結果如下
組態檔.txt
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
雖然這實際上導致如下
組態檔.txt
multiconfig:new-devel:new-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
雖然我還沒有弄清楚為什么更多的條目被替換為'[EMPTY]',但我發現'deploy '上的' '沒有被決議,必須以某種方式轉義,形狀,或形式。鑒于這些 sed 操作是動態的,我不能簡單地在“ ”前面添加一個 \。首先,如何確保“ ”被決議為要在 sed 操作中搜索的字串的一部分?
其次,我可能誤解了 sed 或我的回圈的一些基本部分,盡管為什么除了第一個匹配項之外的所有內容都被替換為“[EMPTY]”?
我感謝任何人可以提供的任何意見,
謝謝大家!
uj5u.com熱心網友回復:
假設您正在嘗試匹配nmb,使用您的NEW_TARGETS陣列,您可以嘗試此實作
#!/usr/bin/env bash
NEW_TARGETS=(multiconfig:new-devel:new-trs-devel multiconfig:newer-devel:newer-trs-devel multiconfig:newest-devel:newest-trs-devel)
i=0
while read -r line; do
sed "/^multiconfig:nmb/s/.*/${NEW_TARGETS[$i]}/;/new\|^$/! c\[EMPTY]" <<< $line
i=$((i 1))
done < input_file
輸出
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
uj5u.com熱心網友回復:
沿著你的路線走:
#!/bin/bash
NEW_TARGETS_ARR=(
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
)
OLD_TARGETS_ARR=(
$(
sed -n '/multiconfig/p' conf.txt |
tail -n 2 |
awk '!seen[$0] ' |
head -n ${#NEW_TARGETS_ARR[@]}
)
)
awk -v from="${OLD_TARGETS_ARR[*]}" -v to="${NEW_TARGETS_ARR[*]}" -v other='[EMPTY]' '
BEGIN{
fromCount = split(from,fromArr)
toCount = split(to,toArr)
for (i=1; i<=fromCount; i )
tr[fromArr[i]] = toArr[i]
}
$1 != "" {
if ($1 in tr)
$1 = tr[$1]
else
$1 = other
}
1
' conf.txt
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
uj5u.com熱心網友回復:
撇開提供的示例和代碼的問題不談,整體設計是基于條目數量的conf.txt假設和所述條目的假設順序。
OP 可能需要考慮重新設計代碼以根據實際字串匹配進行更改。
與此同時,另一種解決方案:
printf "%s\n" ${TARGETS}
printf "\n"
printf "[EMPTY]%.0s\n" {1..3}
printf "\n"
printf "[EMPTY]%.0s\n" {1..3}
這會產生:
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
上一個答案
對 OP 當前代碼的一個小改動:
- 啟用正則運算式匹配 (
-E) - 用 0 個或多個空格后跟 EOL (
$)終止搜索模式
將此滾動到 OP 的當前代碼中:
for i in ${!OLD_TARGETS_ARR[@]}
do
if [ "${NEW_TARGETS_ARR[$i]}" = "" ]; then
NEW_TARGETS_ARR[$i]="[EMPTY]"
fi
sed -iE "s/${OLD_TARGETS_ARR[$i]}[[:space:]]*$/${NEW_TARGETS_ARR[$i]}/" conf.txt
done
這會產生:
$ cat conf.txt
multiconfig:nmb-devel:nmb-trs-devel
multiconfig:new-devel:new-trs-devel
multiconfig:newer-devel:newer-trs-devel
multiconfig:newest-devel:newest-trs-devel
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
[EMPTY]
筆記:
- 這與 OP 的預期輸出不同,但我不知道這是否是 OP 的錯字
- OP宣告操作沒有問題,
OLD_TARGETS_ARR/sed/tail但是...... - 正是這個
tail操作未能拉multiconfig:nmb-devel:nmb-trs-devel入陣列 - 當唯一用于“匹配”舊行和新行的是陣列的數字索引時,這反過來又會拋出替換
- I'm guessing OP probably wants a different design that performs the matching based on actual strings (eg, HatLess' answer, though this one is also prone to potential issues if the lines are not in the 'correct' order in the original
conf.txt) ... ???
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/445465.html
