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
Assign a Shell variable in AWK
提问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 个目录是不变的
##代码##
