我正在使用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
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其更改为:
#!/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
Run Code Online (Sandbox Code Playgroud)
当我进行上述更改以迭代结果时,结果全部搞砸了.我怀疑我的使用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">
Run Code Online (Sandbox Code Playgroud)
但是,当我进行更改时,它显示为(截断):
$ ./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"
Run Code Online (Sandbox Code Playgroud)
查看结果,for in当我希望它使用行分隔符时,似乎使用了空格分隔符.我该如何更改?
tl;博士:
for i in ls -d Module*; do到for i in Module*/;dofor 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
Run Code Online (Sandbox Code Playgroud)
同
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")
Run Code Online (Sandbox Code Playgroud)
请参阅下面的完整讨论.
for i in ls -d Module*; do将简单地枚举令牌ls,-d和(可能膨胀)Module*,而不是列举输出从ls命令.
要纠正这个直接问题,你必须使用命令substitution(for i in $(ls -d Module*; do)),但这是不可取的,因为直接使用globbing(路径名扩展)是一个强大而合适的解决方案:for i in Module*/; do
类似地,不建议使用for循环逐行解析命令输出,因为输出受到单词拆分以及其他shell扩展的影响.
实际上,for循环枚举了以空格分隔的标记而不是整行.
使用while带有IFS= read -r通过进程替换提供的输入的循环是正确的方法 - 它确保未经修改地读取行.
此外,通常建议对引用变量引用进行双引号以避免不必要的shell扩展.
因此,修改后的代码形式为:
shopt -s nullglob # ensure that a glob matching nothing expands to empty string
for i in Module*/; do
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"
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")
fi
fi
done
Run Code Online (Sandbox Code Playgroud)