bash 在 AWK 中分配一个 Shell 变量

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

Assign a Shell variable in AWK

bashshellunixawk

提问by Ravi

I have strings like this

我有这样的字符串

/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt
/home/rm/home-scripts/originals/audicerttest2/incoming/TEST040512.txt
/home/rm/home-scripts/originals/audicerttest3/incoming/TEST040513.txt

etc..I want to extract strings 'audicerttest/incoming', audicerttest2/incoming' etc into a shell variable and use it later in the script. I tried something like this.

等等..我想将字符串 'audicerttest/incoming', audicerttest2/incoming' 等提取到一个 shell 变量中,然后在脚本中使用它。我试过这样的事情。

for file in `find ${ROOT}/* -type f | grep -v -f test.txt`
do
let count++
echo ${count}: ${file}
echo ${file} | eval $(awk '{split(
/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt
,a,"/"); print "abc=a[6]/a[7]"}' < /dev/null) echo abc====$abc done

but its not giving any output for abc.

但它没有为 abc 提供任何输出。

回答by sampson-chen

There are a number of issues, but let's isolate problems and tackle them one at a time.

有很多问题,但让我们隔离问题并一次解决一个。

Given- Raw string:

给定- 原始字符串:

audicerttest/incoming

Desired Output- You want this part to be saved in a variable:

所需输出- 您希望将此部分保存在变量中:

string="/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt"
parsed=$(awk 'BEGIN{FS=OFS="/"} {print , }' <<< ${string})

How-To- This will do it:

操作方法- 这将做到:

/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt
/home/rm/home-scripts/originals/audicerttest2/incoming/TEST040512.txt
/home/rm/home-scripts/originals/audicerttest3/incoming/TEST040513.txt


In general, suppose you have a file called input_file.txt:

通常,假设您有一个名为 的文件input_file.txt

awk 'BEGIN{FS=OFS="/"} {print , }' input_file.txt > parsed_vars.txt

You can do:

你可以做:

audicerttest/incoming
audicerttest2/incoming
audicerttest3/incoming

And parsed_vars.txtwill contain:

parsed_vars.txt将包含:

echo ${file} | eval $(awk '{split(
echo {$file} | awk ... 
,a,"/"); print "abc=a[6]/a[7]"}' < /dev/null)


Some explanations:

一些解释:

  • parsed=$(...)- spawn a subshell and save the output to stdoutwithin that subshell to the variable parsed
  • awk 'BEGIN{FS=OFS="/"}- invoke awkand set delimiter as /for both input and output.
  • {print $6, $7}'- based on the format of your raw strings, you want to print the 6th (audicerttest) and the 7th (incoming) fields.
  • <<< ${string}is the notation for using herestring
  • input_file.txt > parsed_vars.txt- read from specified input file, and redirect output to an output file.
  • parsed=$(...)- 生成一个子shell并将输出保存到stdout该子shell中的变量parsed
  • awk 'BEGIN{FS=OFS="/"}-为输入和输出调用awk和设置分隔符/
  • {print $6, $7}'- 根据原始字符串的格式,您想要打印第 6 个(audicerttest)和第 7 个(传入)字段。
  • <<< ${string}是使用herestring的符号
  • input_file.txt > parsed_vars.txt- 从指定的输入文件读取,并将输出重定向到输出文件。

回答by Karoly Horvath

eval $(echo $file | awk '{split(
abc=$(echo $file | awk '{split(
 cut -d / --output-delimiter / -f6,7
,a,"/"); print a[6]"/"a[7]}')
,a,"/"); print "abc="a[6]"/"a[7]""}')

Okay, a couple of problems here.

好的,这里有几个问题。

awkis reading from /dev/null, which doesn't make any sense, guess you want to process the filename:

awk正在读取/dev/null,这没有任何意义,猜测您要处理文件名:

string="/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt"

"a[6]"is the string a[6], no substitution is made.

"a[6]"是字符串a[6],不进行替换。

Now eval the whole thing:

现在评估整个事情:

IFS=/ a=( $string ) printf -v parsed '%s/%s' "${a[@]:5:2}"

Finally, eval is evil, why don't you directly set the variable?

最后,eval是邪恶的,为什么不直接设置变量呢?

path=/home/rm/home-scripts/originals/audicerttest/incoming/TEST040511.txt

On a personal note, I thing this is a bit more clear:

就个人而言,我认为这更清楚一点:

IFS=/ split=(${path})
path_part="${split[5]}/${split[6]}"

回答by gniourf_gniourf

Here's a pure bash solution, not using any overkill awkand not using any evil evaland not using any subshells:

这是一个纯粹的 bash 解决方案,不使用任何矫枉过正awk,不使用任何邪恶eval,也不使用任何子shell:

You have this string:

你有这个字符串:

while read path; do
    dirname=$(dirname $path)
    abc=${dirname#/home/rm/home-scripts/originals/}
    echo "abc===$abc"
done < filename

You want a string that contains the 5th and 6th fields (where separation is /) in a variable parsed. Let's go:

您需要一个字符串,其中包含/变量中的第 5 和第 6 个字段(其中分隔为)parsed。我们走吧:

##代码##

回答by Mat

With only bash arrays, you could do the following:

仅使用 bash 数组,您可以执行以下操作:

Assuming:

假设:

##代码##

Then:

然后:

##代码##

$splitwill be an array, with element 0 empty, element one home, element 2 rm, etc. With that you just need to concatenate the elements you want to get the part you like.

$split将是一个数组,元素 0 为空,元素 1 home,元素 2rm等。这样你只需要连接你想要获得你喜欢的部分的元素。

回答by glenn Hymanman

Nobody has suggested simple parameter expansionto manipulate the strings. I'm assuming that the first 4 directories are constant

没有人建议使用简单的参数扩展来操作字符串。我假设前 4 个目录是不变的

##代码##