
我有一個具有如下值的變量
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
根據逗號將變數分成幾部分。第二行,從內到外工作:
- 輸出第一個值(例如「dog」)、等號,然後輸出第二個值,
1
輸出以, 等號為後綴的第一個值,然後輸出第二個值,- 輸出第一個值,後綴為
2
, 等號,然後是第三個值, 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
。如果需要,您可以透過從腳本中的print
和printf
語句中輸出適當的參考來修復此問題perl
。和/或定義$newline
為 bash 陣列而不是字串。留給讀者作為練習,因為我已經展示了這裡使用的足夠的原理/技術。
如果您希望將它們聲明為導出變量,請使用:
declare -x $newline
請參閱help declare
以了解更多詳細資訊。
順便說一句,在 中ksh
,您可以使用typeset
代替declare
。 typeset
也受支援bash
但被認為已過時(請參閱help typeset
)bash
。
最後:您確定您不喜歡使用 shell 陣列變數(例如dog[0]=/path1,/path2
、dog[1]=/path1
和dog[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