我想爲多分區系統的自動設置創建一個腳本。第一個動作是BASH將文本文件逐行轉換爲變量
lspci | grep -i 'vga\|graphic' | cut -b 1-7 > text.txt
現在我想將文件的兩行變量。我dowdy解決方案是這樣的:
VAR1=$(head -n 1 text.txt)
VAR2=$(tail -n 1 text.txt)
它也可以,但是,可能有更好的解決方案,將文本文件逐行轉換爲變量。
我想爲多分區系統的自動設置創建一個腳本。第一個動作是BASH將文本文件逐行轉換爲變量
lspci | grep -i 'vga\|graphic' | cut -b 1-7 > text.txt
現在我想將文件的兩行變量。我dowdy解決方案是這樣的:
VAR1=$(head -n 1 text.txt)
VAR2=$(tail -n 1 text.txt)
它也可以,但是,可能有更好的解決方案,將文本文件逐行轉換爲變量。
如果您可以將文本文件格式化爲名稱值對,則可以使用bash associative arrays來存儲和引用每個項目。請注意,在此代碼中使用=
作爲分隔名稱值對的分隔符。
#read in fast config (name value pair file)
declare -A MYMAP
while read item; do
NAME=$(cut -d "=" -f1 <<<"$item")
VALUE=$(cut -d "=" -f2 <<<"$item")
MYMAP["$NAME"]="$VALUE"
done <./config_file.txt
#size of map
MYMAP_N=${#MYMAP[@]}
#make a list of keys
KEYS=("${!MYMAP[@]}")
#dereference map
SELECTION="${MYMAP["my_first_key"]}"
爲什麼在普通shell變量可以工作時使用關聯數組?或者,如果源文件在謹慎的控制下,只需使其有效的外殼分配和源代碼即可。 – 2014-10-31 16:08:06
「將文本文件逐行轉換爲變量」......誰知道他打算如何使用這些變量?說他只有2個變量,但我的解決方案是一般的 – ldgorman 2014-10-31 16:10:17
所以我的兩個建議,除非任何密鑰都不是有效的shell標識符我的觀點是shell變量已經是一個你不需要的key = value存儲引入關聯數組(和bash 4+要求)以訪問其中的一個 – 2014-10-31 16:15:04
如果值不使用數組變量包含空格,在bash
:
declare -a vars
eval "vars=(`echo line1; echo line2`)" # the `echo ...` simulates your command
echo number of values: ${#vars[@]}
for ((I = 0; I < ${#vars[@]}; ++I)); do
echo value \#$I is ${vars[$I]}
done
echo all values : ${vars[*]}
的關鍵是產生初始化與該數組的語句,然後eval
它。
如果值有空格/特殊字符,則可能需要轉義/引用。
不要使用'eval';您可以使用循環向數組逐個添加行。 – chepner 2014-10-31 18:48:09
@chepner,the循環變體將是多餘的,因爲它是alr伊迪在ldgorman的回答中展示了(與聯合陣列)。 – Dummy00001 2014-10-31 21:15:58
我的觀點是,當有其他選擇時,不要使用'eval'。一般來說,這是不安全的,在不需要時使用它是一個不好的習慣。 – chepner 2014-11-01 13:11:09
下應該達到正是你在做什麼,不使用臨時文件現在
#!/bin/bash
{ read -r var1 _ && read -r var2 _; } < <(lspci | grep -i 'vga\|graphics')
,如果你從lspci | grep -i 'vga\|graphics'
(或只是一個或無)的幾行,你可能想更多的東西一般情況下,即,把結果在一個數組:
#!/bin/bash
var=()
while read -r f _; do var+=("$f"); done < <(lspci | grep -i 'vga\|graphics')
# display the content of var
declare -p var
如果您有最新的Bash的版本,你愛mapfile
和awk
(但誰不?),你也可以這樣做這個:
#!/bin/bash
mapfile -t var < <(lspci | awk 'tolower($0) ~ /var|graphics/ { print $1 }')
# display the content of var
declare -p var
對於純擊可能性(除了lspci
,當然):
#!/bin/bash
shopt -s extglob
var=()
while read -r v rest; do
[[ ${rest,,} = *@(vga|graphics)* ]] && var+=("$v")
done < <(lspci)
# display var
declare -p var
這使用:的rest
${rest,,}
*@(vga|graphics)*
(完全避免正則表達式)。read VAR1 VAR2 < <(sed -n '1p;$p' myfile | tr '\n' ' ')
這應該做你需要它使用進程替換來打印你想要的線,然後將其重定向到變量,如果需要不同的線路只是建立這種說法,因爲你需要用爲了循環放置任何你想要的線,如果你想要它們都使用wc來計算線,然後建立VAR1 .. VAR [n]和sed -n'1p; 2p; 3p .. [n] p'然後你就可以eval建立的聲明。
一旦你提取了變量,變量會被使用嗎? – 2014-10-31 15:48:43
你想要處理多少行。由於命令行沒有數組,所以這可能會變得笨重,因此每個變量都必須被下標。討厭。 – 2014-10-31 15:50:54
我將在xorg配置文件中將它們與sed一起使用。實際上只有兩行,否則腳本會失敗。它也適用於頭部/尾部,但它不是那麼優雅......類似於VAR1 = firstlineoffile,VAR2 = secondlineoffile等等 – 2014-10-31 15:53:24