我想为多系统系统制作一个自动设置脚本。第一个行动是
lspci | grep -i 'vga\|graphic' | cut -b 1-7 > text.txt
现在我想把文件的两行放入变量中。我的糟糕解决方案是:
VAR1=$(head -n 1 text.txt)
VAR2=$(tail -n 1 text.txt)
它也有效,但是,将文本文件逐行转换为变量可能是更好的解决方案。
答案 0 :(得分: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,并且您喜欢mapfile
和awk
(但谁不喜欢?),您也可以这样做:
#!/bin/bash
mapfile -t var < <(lspci | awk 'tolower($0) ~ /var|graphics/ { print $1 }')
# display the content of var
declare -p var
对于纯粹的Bash可能性(当然除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)*
(完全避免正则表达式)。答案 1 :(得分: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"]}"
答案 2 :(得分: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
。
如果值包含空格/特殊字符,则可能需要转义/引用。
答案 3 :(得分:0)
read VAR1 VAR2 < <(sed -n '1p;$p' myfile | tr '\n' ' ')
这应该做你需要的东西它使用进程替换来打印你想要的行然后将它们重定向到变量,如果你想要不同的行只需要构建这个语句,你需要使用for循环放置你想要的任何行你希望他们都使用wc来计算线数,然后建立VAR1 .. VAR [n]和sed -n&#39; 1p; 2p; 3p .. [n] p&#39;然后你可以评估构建的语句。