我正在使用bash脚本来识别某些内容的使用位置,然后找到相应的引用(名称)。
脚本是:
#!/bin/bash
echo "running, searching for instances of ${1:0:1}/$1"
for i in ls -d Module*; do
if [ -d "$i" ]; then
if [ -f $i/003.Design/003.Data.efx ]; then
if grep -qe "Module-0000/003.Design/005.Types/${1:0:1}/$1" $i/003.Design/003.Data.efx; then
echo $i $i/003.Design/003.Data.efx
grep -B 4 "Module-0000/003.Design/005.Types/${1:0:1}/$1" $i/003.Design/003.Data.efx | grep "name"
fi
fi
fi
done
我正在尝试将其更改为:
#!/bin/bash
echo "running, searching for instances of ${1:0:1}/$1"
for i in ls -d Module*; do
if [ -d "$i" ]; then
if [ -f $i/003.Design/003.Data.efx ]; then
if grep -qe "Module-0000/003.Design/005.Types/${1:0:1}/$1" $i/003.Design/003.Data.efx; then
echo $i $i/003.Design/003.Data.efx
for j in `grep -B 4 "Module-0000/003.Design/005.Types/${1:0:1}/$1" $i/003.Design/003.Data.efx | grep "name"` ; do
echo $j
done
fi
fi
fi
done
当我进行上述更改以迭代结果时,结果全部搞砸了。我怀疑我对for
的使用不正确。
我应该注意到更改前的结果是:
$ ./findEllipseType.sh AveragePrice
running, searching for instances of A/AveragePrice
Module-3110 Module-3110/003.Design/003.Data.efx
<ownedAttribute xmi:id="_P7sUcAg7EdysLcyAWbYneA" name="EstPrice">
Module-3140 Module-3140/003.Design/003.Data.efx
<ownedAttribute xmi:id="_Z2v4IaW-EduyI4lEFgFo8g" name="StoresSalePrice">
<ownedAttribute xmi:id="_bpCVJaW-EduyI4lEFgFo8g" name="StoresSalePrice">
<ownedAttribute xmi:id="_j0crsMnVEeOm9cfLF6jryw" name="EstPrice">
Module-3210 Module-3210/003.Design/003.Data.efx
<ownedAttribute xmi:id="_dYMlpaW-EduyI4lEFgFo8g" name="GrossPriceP">
<ownedAttribute xmi:id="_duQVQqW-EduyI4lEFgFo8g" name="GrossPriceP">
<ownedAttribute xmi:id="_dujQI6W-EduyI4lEFgFo8g" name="CurrNetPrP">
<ownedAttribute xmi:id="_eNZISqW-EduyI4lEFgFo8g" name="GrossPriceP">
<ownedAttribute xmi:id="_eNi5QKW-EduyI4lEFgFo8g" name="PrevGpP">
<ownedAttribute xmi:id="_eNsqQqW-EduyI4lEFgFo8g" name="CurrNetPrP">
<ownedAttribute xmi:id="_eNsqSqW-EduyI4lEFgFo8g" name="PrevNetPrP">
<ownedAttribute xmi:id="_fRV4kqW-EduyI4lEFgFo8g" name="CurrNetPrP">
<ownedAttribute xmi:id="_fRV4mqW-EduyI4lEFgFo8g" name="GrossPriceP">
<ownedAttribute xmi:id="_fgsjMqW-EduyI4lEFgFo8g" name="EstPrice">
<ownedAttribute xmi:id="_fg1tJaW-EduyI4lEFgFo8g" name="ActGrossPr">
Module-3560 Module-3560/003.Design/003.Data.efx
<ownedAttribute xmi:id="_xM44IKW-EduyI4lEFgFo8g" name="UnitPrice">
<ownedAttribute xmi:id="_xOYF8KW-EduyI4lEFgFo8g" name="UnitPrice">
<ownedAttribute xmi:id="_xdbOkKW-EduyI4lEFgFo8g" name="AmendPrice">
但是当我做出改变时,它显示为(截断):
$ ./findEllipseType.sh AveragePrice
running, searching for instances of A/AveragePrice
Module-3110 Module-3110/003.Design/003.Data.efx
<ownedAttribute
xmi:id="_P7sUcAg7EdysLcyAWbYneA"
name="EstPrice">
Module-3140 Module-3140/003.Design/003.Data.efx
<ownedAttribute
xmi:id="_Z2v4IaW-EduyI4lEFgFo8g"
name="StoresSalePrice">
<ownedAttribute
xmi:id="_bpCVJaW-EduyI4lEFgFo8g"
name="StoresSalePrice">
<ownedAttribute
xmi:id="_j0crsMnVEeOm9cfLF6jryw"
name="EstPrice">
Module-3210 Module-3210/003.Design/003.Data.efx
<ownedAttribute
xmi:id="_dYMlpaW-EduyI4lEFgFo8g"
查看结果,当我希望它使用行分隔符时,for in
似乎正在使用空格分隔符。我该如何改变呢?
答案 0 :(得分:6)
<强> TL;博士强>:
for i in ls -d Module*; do
更改为for i in Module*/;do
for j in `grep -B 4 "Module-0000/003.Design/005.Types/${1:0:1}/$1" $i/003.Design/003.Data.efx | grep "name"` ; do
echo $j
done
与
while IFS= read -r j; do
echo "$j"
done < <(grep -B 4 "Module-0000/003.Design/005.Types/${1:0:1}/$1" "$i/003.Design/003.Data.efx" | grep "name")
请参阅下面的完整讨论。
for i in ls -d Module*; do
只会枚举令牌ls
,-d
和(可能已展开)Module*
,而不是枚举来自{{1}的输出命令。
要纠正这个直接问题,您必须使用命令替换(ls
),但不可取,因为直接使用 globbing(路径名扩展)< / em>是强大而合适的解决方案:for i in $(ls -d Module*; do)
同样,不建议使用for i in Module*/; do
循环逐行解析命令输出,因为输出受分词以及其他shell扩展的影响。
有效地,for
循环枚举以空格分隔的标记而不是整行。
使用for
循环while
,通过process substitution提供输入,是正确的方法 - 它可以确保不经修改地读取行。
此外,通常建议双引号变量引用以避免不必要的shell扩展。
因此修改后的代码形式为:
IFS= read -r