2012-11-29 36 views
2

我有这样指定一个Shell变量AWK

/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字符串要提取字符串“audicerttest /来电”,audicerttest2 /入”等成shell变量后来在使用它脚本。我尝试过这样的事情。

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

但它没有给出abc的输出。

回答

5

有一些问题,但让我们找出问题并解决他们一次一个。

鉴于 - 原始字符串:

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

所需的输出 - 你想这部分被保存在一个变量:

audicerttest/incoming 

操作方法 - 这将做它:

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

一般情况下,假设你有一个名为input_file.txt文件:

/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 

你可以这样做:

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

而且parsed_vars.txt将包含:

audicerttest/incoming 
audicerttest2/incoming 
audicerttest3/incoming 

几点说明:

  • parsed=$(...) - 生成一个子外壳和子外壳内的输出到stdout保存到变量parsed
  • awk 'BEGIN{FS=OFS="/"} - 调用awk和分隔符设定为/用于输入和输出。
  • {print $6, $7}' - 基于原始字符串的格式,您希望打印第6个(audicerttest)和第7个(传入)字段。
  • <<< ${string}是用于使用herestring
  • input_file.txt > parsed_vars.txt符号 - 从指定的输入文件中读取,并输出重定向到一个输出文件中。
1
echo ${file} | eval $(awk '{split($0,a,"/"); print "abc=a[6]/a[7]"}' < /dev/null) 

好的,这里有几个问题。

awk/dev/null,这没有任何意义阅读,估计你要处理的文件名:

echo {$file} | awk ... 

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

现在EVAL整个事情:

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

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

abc=$(echo $file | awk '{split($0,a,"/"); print a[6]"/"a[7]}') 

就我个人而言,我的事情这是一个比较明确的:

cut -d/--output-delimiter/-f6,7 
+0

你方法的主要问题是无用的'eval'。 'eval'是邪恶的!不提无用的subhells使用。 –

+0

我刚刚更新了我的答案......他正在使用效率低下的工具来完成任务,但是(我希望)他问的是为什么它不起作用,而不仅仅是要求其他解决方案。所以,不知道为什么downvote。 –

+0

我是Shell的总新手。我同意有太多的错误。感谢您纠正这些问题。 – Ravi

1

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

你有这样的字符串:

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

你想要一个字符串包含变量parsed中的第5个和第6个字段(其中的间隔为/)。让我们去:

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

由于只有bash的数组,你可以做到以下几点:

假设:

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

然后:

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

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

0

没有人建议简单的parameter expansion来操纵字符串。我假设前4个目录是不变的

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