Linux Unix shell 脚本:将文件中的值赋给变量到 while 循环中,并在循环外使用此值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4304390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:10:15  来源:igfitidea点击:

Unix shell scripting: assign value from file to variable into while loop, and use this value outside the loop

linuxshellunixwhile-loop

提问by sangi

I'm writing a shell script, where I have to extract the contents of a file which is of type:

我正在编写一个 shell 脚本,我必须在其中提取以下类型的文件的内容:

type1|valueA
type2|valueB
type1|valueC
type2|valueD
type3|valueE
....
typen|valueZ.

type1|valueA
type2|valueB
type1|valueC
type2|valueD
type3|valueE
....
typen|valueZ。

For each type in column_1, I have a target variable, which concatenates the values of the same type, to get a result like this:

对于 中的每种类型column_1,我都有一个目标变量,它连接相同类型的值,以获得如下结果:

var1=valueA,valueC
var2=valueB,valueD
var3=valueE
.....

var1=valueA,valueC
var2=valueB,valueD
var3=valueE
.....

Script implements something like this:

脚本实现如下:

var1="HELLO"  
var2="WORLD"  
...  
cat $file | while read record; do  
   #estract column_1 and column_2 from $record    
if [ $column_1 = "tipo1" ]; then  
   var1="$var1, column_2"  ## column_2 = valueB
elif ....  
....  
fi  
done

But when I try to use the value of any of the variables where I chained column_2:

但是当我尝试使用我链接的任何变量的值时column_2

    echo "$var1 - $var2"   

I get the original values:

我得到原始值:

    HELLO - WORLD.    

Searching the internet, I read that the problem is related to the fact that the pipeline creates a subshell where the actual values are copied.

在互联网上搜索,我读到问题与管道创建了一个子shell 来复制实际值有关。

Is there a way to solve this problem!?

有没有办法解决这个问题!?

Above all, there is a way that would fit for all types of shells, in fact, this script must run potentially on different shells!? I do not want to use file support on which to write the partial results.

最重要的是,有一种方法可以适用于所有类型的 shell,事实上,这个脚本必须可能在不同的 shell 上运行!?我不想使用文件支持来写入部分结果。

回答by Didier Trosset

Oneliner:

单线:

for a in `awk "-F|" '{print ;}' test | sort -u` ; do echo -n "$a =" ; grep -e "^$a" test | awk "-F|" '{ printf(" %s,", );}' ; echo "" ; done

回答by Paused until further notice.

You don't need to use cat. Piping something into whilecreates a subshell. When the subshell exits, the values of variables set in the loop are lost (as would be directory changes using cdas another example. Instead, you should redirect your file into the done:

您不需要使用cat. 将某些东西放入管道中while会创建一个子外壳。当子shell退出时,循环中设置的变量值将丢失(cd作为另一个示例的目录更改也会丢失。相反,您应该将文件重定向到done

while condition
do
    # do some stuff
done < inputfile

By the way, instead of:

顺便说一句,而不是:

while read record

you can do:

你可以做:

while IFS='|' read -r column1 column2

回答by BMW

Using awk

使用 awk

awk '{a[]=a[]==""?:a[] OFS }
END{for (i in a) print i"="a[i]}' FS=\| OFS=, file  

type1=valueA,valueC
type2=valueB,valueD
type3=valueE