2014-10-31 86 views
2

我想爲多分區系統的自動設置創建一個腳本。第一個動作是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) 

它也可以,但是,可能有更好的解決方案,將文本文件逐行轉換爲變量。

+0

一旦你提取了變量,變量會被使用嗎? – 2014-10-31 15:48:43

+0

你想要處理多少行。由於命令行沒有數組,所以這可能會變得笨重,因此每個變量都必須被下標。討厭。 – 2014-10-31 15:50:54

+0

我將在xorg配置文件中將它們與sed一起使用。實際上只有兩行,否則腳本會失敗。它也適用於頭部/尾部,但它不是那麼優雅......類似於VAR1 = firstlineoffile,VAR2 = secondlineoffile等等 – 2014-10-31 15:53:24

回答

0

如果您可以將文本文件格式化爲名稱值對,則可以使用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"]}" 
+0

爲什麼在普通shell變量可以工作時使用關聯數組?或者,如果源文件在謹慎的控制下,只需使其有效的外殼分配和源代碼即可。 – 2014-10-31 16:08:06

+0

「將文本文件逐行轉換爲變量」......誰知道他打算如何使用這些變量?說他只有2個變量,但我的解決方案是一般的 – ldgorman 2014-10-31 16:10:17

+0

所以我的兩個建議,除非任何密鑰都不是有效的shell標識符我的觀點是shell變量已經是一個你不需要的key = value存儲引入關聯數組(和bash 4+要求)以訪問其中的一個 – 2014-10-31 16:15:04

0

如果值不使用數組變量包含空格,在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它。

如果值有空格/特殊字符,則可能需要轉義/引用。

+0

不要使用'eval';您可以使用循環向數組逐個添加行。 – chepner 2014-10-31 18:48:09

+0

@chepner,the循環變體將是多餘的,因爲它是alr伊迪在ldgorman的回答中展示了(與聯合陣列)。 – Dummy00001 2014-10-31 21:15:58

+0

我的觀點是,當有其他選擇時,不要使用'eval'。一般來說,這是不安全的,在不需要時使用它是一個不好的習慣。 – chepner 2014-11-01 13:11:09

1

下應該達到正是你在做什麼,不使用臨時文件現在

#!/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的版本,你愛mapfileawk(但誰不?),你也可以這樣做這個:

#!/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

0

read VAR1 VAR2 < <(sed -n '1p;$p' myfile | tr '\n' ' ')

這應該做你需要它使用進程替換來打印你想要的線,然後將其重定向到變量,如果需要不同的線路只是建立這種說法,因爲你需要用爲了循環放置任何你想要的線,如果你想要它們都使用wc來計算線,然後建立VAR1 .. VAR [n]和sed -n'1p; 2p; 3p .. [n] p'然後你就可以eval建立的聲明。