bash 一次将多个字段设置为 awk 变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12739515/
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-09-18 03:28:20  来源:igfitidea点击:

Setting multiple field to awk variables at once

bashawk

提问by Nap

I am trying to set an awk variable field to several field at once.

我正在尝试将 awk 变量字段一次设置为多个字段。

Right now I can only set the variables one by one.

现在我只能一一设置变量。

for line in `cat file.txt`;do
    var1=`echo $line | awk -F, '{print }'`
    var2=`echo $line | awk -F, '{print }'`
    var3=`echo $line | awk -F, '{print }'`

    #Some complex code....
done

I think this is costly cause it parses the linux variable several times. Is there a special syntax to set the variable at once? I know that awk has a BEGIN and END block but the reason I am trying to avoid the BEGIN and END block is to avoid nested awk.

我认为这很昂贵,因为它会多次解析 linux 变量。是否有特殊的语法可以一次设置变量?我知道 awk 有一个 BEGIN 和 END 块,但我试图避免 BEGIN 和 END 块的原因是避免嵌套 awk。

I plan to place another loop and awk code in the #Some complex code.... part.

我计划在 #Some complex code.... 部分放置另一个循环和 awk 代码。

for line in `cat file.txt`;do
    var1=`echo $line | awk -F, '{print }'`
    var2=`echo $line | awk -F, '{print }'`
    var3=`echo $line | awk -F, '{print }'`

    for line2 in `cat file_old.txt`;do
        vara=`echo $line2 | awk -F, '{print }'`
        varb=`echo $line2 | awk -F, '{print }'`

        # Do comparison of $var1,var2 and $vara,$varb , then do something with either
    done
done

回答by newfurniturey

You can use the IFSinternal field separator to use a comma (instead of whitespace) and do the assignments in a whileloop:

您可以使用IFS内部字段分隔符来使用逗号(而不是空格)并在while循环中进行分配:

SAVEIFS=$IFS;
IFS=',';
while read line; do
    set -- $line;
    var1=;
    var2=;
    var3=;
    ...
done < file.txt

IFS=$SAVEIFS;

This will save a copy of your current IFS, change it to a ,character, and then iterate over each line in your file. The line set -- $line;will convert each word (separated by a comma) into a numeric-variable ($1, $2, etc.). You can either use these variables directly, or assign them to other (more meaningful) variable names.

这将保存当前 的副本IFS,将其更改为一个,字符,然后遍历文件中的每一行。线set -- $line;将每个字(由逗号分隔)转换成数字变量($1$2等)。您可以直接使用这些变量,也可以将它们分配给其他(更有意义的)变量名称。

Alternatively, you could use IFSwith the answer provided by William:

或者,您可以使用IFS威廉提供的答案:

IFS=',';
while read var1 var2 var3; do
    ...
done < file.txt

They are functionally identical and it just comes down to whether or not you want to explicitly set var1=$1or have it defined in the while-loop's head.

它们在功能上是相同的,这取决于您是否要var1=$1while-loop 的头部显式设置或定义它。

回答by William Pursell

Why are you using awkat all?

你为什么要使用awk

while IFS=, read var1 var2 var3; do
  ...
done < file.txt

回答by V H

#!/bin/bash    
FILE="/tmp/values.txt"

    function parse_csv() { 
    local lines=$lines;
    > $FILE
    OLDIFS=$IFS;
    IFS=","
    i=0
    for val in ${lines}
    do
      i=$((++i))
      eval var${i}="${val}"
    done
    IFS=$OLDIFS;
    for ((j=1;j<=i;++j))
    do
      name="var${j}"
      echo ${!name} >> $FILE
    done

    }

    for lines in `cat file_old.txt`;do
     parse_csv;
    done

The problem you have described has only got 3 values, would there be a chance that 3 values may differ and be 4 or 5 or undefined ?

您描述的问题只有 3 个值,是否有可能 3 个值可能不同并且是 4 或 5 或未定义?

if so the above will parse through the csv line by line and output each value at a time on a new line in a file called /tmp/values.txt

如果是这样,上面将逐行解析 csv 并在名为 /tmp/values.txt 的文件中的新行上一次输出每个值

feel free to modify to match your requirements its far more dynamic than defining 3 values

随意修改以满足您的要求,它比定义 3 个值更具动态性