通过grep逐行迭代结果,不按空格分隔

时间:2014-05-14 02:38:09

标签: bash grep

我正在使用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似乎正在使用空格分隔符。我该如何改变呢?

1 个答案:

答案 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