Bash 在for循环中分配变量

Bash 在for循环中分配变量,bash,shell,loops,unix,scripting,Bash,Shell,Loops,Unix,Scripting,我有一个名为school.test的文件,它看起来是这样的: David maths Sam maths Sam english Simon french Simon english for line in `cat/home/school.test` do positionClient -name [variable=David] -class [variable=math] done 我想写一个for循环,它逐行读取这个

我有一个名为school.test的文件,它看起来是这样的:

David       maths
Sam         maths
Sam         english
Simon       french
Simon       english
for line in `cat/home/school.test`
do
positionClient -name [variable=David] -class [variable=math]
done
我想写一个for循环,它逐行读取这个txt文件,并将该行读取的值分配给不同的变量,然后通过命令运行它。问题是我不知道如何将第一个值设置为变量,将第二个值设置为不同的变量

例如,For循环读取的第一行内容如下:

David       maths
Sam         maths
Sam         english
Simon       french
Simon       english
for line in `cat/home/school.test`
do
positionClient -name [variable=David] -class [variable=math]
done
等等等等。我该怎么做

$while read name subject
$ while read name subject
> do
>   echo "Name: $name, Subject: $subject"
> done <<< 'David       maths
> Sam         maths
> Sam         english
> Simon       french
> Simon       english'
Name: David, Subject: maths
Name: Sam, Subject: maths
Name: Sam, Subject: english
Name: Simon, Subject: french
Name: Simon, Subject: english
>做 >echo“Name:$Name,Subject:$Subject”
>完成您可以使用内置的
read
进行以下操作:

cat /home/school.test | while read name class ; do 
    positionClient -name "$name" -class "$class"
done
我更喜欢带有
cat
的管道,因为在
循环中使用I/O重定向时,使用
循环看起来有点奇怪(“该文件的
完成了什么操作?”):

读取名称类时;做
positionClient-名称“$name”-类“$class”
完成

请注意,如果希望在循环体和循环后的代码之间共享变量,则必须使用第二种方法。使用管道时,
while
循环将在子shell中执行(在不同的过程中),循环结束时,对循环内部变量的所有修改都将丢失。

有多种方法将值转换为不同的变量。其他答案中已经提到了一种方法,即使用内置的
read

请允许我解释另一种方法。下面是一种使用
awk
的方法。它可能不是最理想的(因为subshell的东西),但它是有效的

for line in `cat school.test`
do
    name=`echo $line | awk '{print $1}'`
    class=`echo $line | awk '{print $2}'`
    positionClient -name "$name" -class "$class"
done

如果坚持使用shell循环,则:

for line in `cat school.test`
do
    set -- $line   # $1 is NAME, and $2 is CLASS. 
    # NB since awk didn't distinguish separator, NO NEED to quote $1, $2
    positionClient -name $1 -class $2
done
或者,这里有一条单行线:

awk 'BEGIN { fmt="positionClient -name %s -class %s\n"; }; { print fmt, $1, $2 }' school.test | sh -x

我不知道题目和这个问题有什么关系。这是一个练习,还是一个实际问题(如工作、非学校、非培训)?我保留“解决问题”的权利,而不是回答问题。为什么?除非OP陈述了一些大意:“这是一个旨在展示如何。。。“我可以假设这不是问题的关键,问题的解决方案可以通过另一种方式更好地解决。至少这应该得到a。问题的解决者需要做更多相关的例子,b。问题解决者必须公开他们的需求。使用重定向看起来一点也不奇怪,并且避免在子shell中运行。要添加到@williampersells注释,它还允许在循环中设置的变量在外部使用(因为它不是子shell)。@williampersell:我同意子shell问题,但是
完成了
对文件做了什么?而且,将输入放在代码块的末尾是很奇怪的。当循环体很大时,这很容易被忽略;做……事。。;完成
以避免UUoC(不必要地使用
cat
)和产生额外的独立子shell?(只是为了添加正式的术语)所以我尝试了这个方法,但它对我不起作用:
在阅读名称主题时,要回显“symbol:$symbol”;echo“inventory:$inventory”done
,您需要阅读“awk”,这是unix中处理(本质上)表的首选(例如非perl)方法。然后,当您熟悉awk时,应该下载RDB,例如搜索/RDB——unix realational database Management、schaefer、manis和jorgenson。它将改变你的生活。质疑“最优”的用法。“最优”应该与性能关系不大,而更多地与简单易读的人有关。并不是说你的不是,而且你已经确定了次优,而没有重新认识到一个awk,如果你坚持的话,可以完成这项工作。请参阅“SET--下面。@MartyMcGowan:你的解决方案很好。而且,我确实理解
集合--
的工作原理。但是请帮助我理解
set
方法如何比
awk
方法具有更好的可读性?我还提到,这是一种方法,而不是唯一的方法。