從單一變數建立與多個變數分配相對應的文本

從單一變數建立與多個變數分配相對應的文本

我有一個具有如下值的變量

line=dog,/path1,/path2

我想要的是從值創建一個變數; iedog應該是變數並且想要得到以下輸出:

dog=/path1,/path2
dog1=/path1
dog2=/path2

同樣,如果我有,line=bull,/val1,/val2我需要以下輸出

bull=/val1,/val2
bull1=/val1
bull2=/val2

請注意,line只有三個值,以逗號分隔。

答案1

我認為這就是你想要做的事情:

line='dog,/path1,/path2'
IFS=', ' read -r -a dog <<< "$line"

echo "$dog"
dog
echo "${dog[1]}"
/path1
echo "${dog[2]}"
/path2 

這假設您的 shell 是 bash。

答案2

這是一個以 bash 為中心的解決方案:

IFS=, read -r -a vars <<<"$line"
printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"

第一行$line根據逗號將變數分成幾部分。第二行,從內到外工作:

  1. 輸出第一個值(例如「dog」)、等號,然後輸出第二個值,
  2. 1輸出以, 等號為後綴的第一個值,然後輸出第二個值,
  3. 輸出第一個值,後綴為2, 等號,然後是第三個值,
  4. printf這三個字串,由換行符號分隔。

正如您的問題一樣,這個答案被硬編碼為在 中包含三個值$line

輸入和輸出範例(前導$是 shell 提示字元):

$ line=dog,/path1,/path2
$ IFS=, read -r -a vars <<<"$line"
$ printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"
dog=/path1,/path2
dog1=/path1
dog2=/path2

您可以輕鬆地將 printf 輸出重新導向到檔案。

答案3

如果您正在使用bash,您可以執行以下操作(使用額外的echo語句來顯示每個階段發生的情況):

$ line=dog,/path1,/path2

$ newline=$(printf "%s\n" "$line" | 
            perl -n -e 'BEGIN {$count=1};
                        my ($var,@values) = split /,/;
                        print "$var=" . join(",",@values);
                        foreach (@values) {
                            printf "%s%i=\"%s\" ",$var, $count++, $_
                        }')

$ echo "$newline"
dog=/path1,/path2 dog1=/path1 dog2=/path2

$ declare $newline

$ declare | grep '^dog'
dog=/path1,/path2
dog1=/path1
dog2=/path2

這用於用逗號perl分隔。$line第一個欄位保存在 中$var,其餘欄位則保存在名為 的陣列中@values。然後它會產生適合與 bashdeclare命令一起使用來設定變數的輸出。

請注意,$newline不是也不應該在該declare行中使用雙引號。如果用雙引號括起來,declare則只會得到一個參數,而不是三個以空格分隔的參數。

這裡缺乏引用的一個令人不快的副作用是declare 將要如果任何欄位值包含空格字元等,則會失敗line=dog,/path /with / spaces,/path2。如果需要,您可以透過從腳本中的printprintf語句中輸出適當的參考來修復此問題perl。和/或定義$newline為 bash 陣列而不是字串。留給讀者作為練習,因為我已經展示了這裡使用的足夠的原理/技術。

如果您希望將它們聲明為導出變量,請使用:

declare -x $newline

請參閱help declare以了解更多詳細資訊。

順便說一句,在 中ksh,您可以使用typeset代替declaretypeset也受支援bash但被認為已過時(請參閱help typesetbash


最後:您確定您不喜歡使用 shell 陣列變數(例如dog[0]=/path1,/path2dog[1]=/path1dog[2]=/path2)而不是單獨的變數嗎?這就是他們存在的目的。

答案4

你可以做這樣的事情。我按照你的方式定義了這條線。接下來,我解析該行中的第一個逗號分隔的標記(我假設這裡對變數名稱有效)。然後,我根據第一個標記建構兩個新變量,並將它們分配給該行中的第二個和第三個以逗號分隔的標記。

line="dog,/path1,/path2"
first="$(echo "${line}" | awk -F, '{ print $1 }')"
eval "${first}1=$(echo "${line}" | awk -F, '{ print $2 }')"
eval "${first}2=$(echo "${line}" | awk -F, '{ print $3 }')"

echo "${dog1}"
/path1
echo "${dog2}"
/path2

相關內容