【问题标题】:How to do a grep to match one line with an offset in a for loop如何执行 grep 以匹配一行与 for 循环中的偏移量
【发布时间】:2019-08-01 09:50:38
【问题描述】:

我想在 for 循环中获得单行 grep 结果并传递到下一个匹配项,而不需要之前的所有其他匹配项。

我尝试了下面的代码,但它没有按预期工作,因为我只想要一行结果。 $nbOfMatches=7
$className=somefile

for i in $(seq 1 $nbOfMatches);
do
    lineCopy=$(grep -m $i 'private ' $className)
    echo "$lineCopy"
done

当前输出:


Occurences found : 7
private $id;
private $id;
private $firstname;
private $id;
private $firstname;
private $lastname;
private $id;
private $firstname;
private $lastname;
private $email;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $address;

预期输出:

Occurences found : 7
private $id;
private $firstname;
private $lastname;
private $email;
private $password;
private $phone;
private $address;

我想知道是否有一种方法可以向 grep 添加偏移匹配,以删除之前的匹配也不会被检测到。或者是否有任何其他解决方案可以实现预期的输出。

【问题讨论】:

  • 我认为你可以在没有循环的情况下做你想做的事,但我不明白你想要什么。 grep 'private ' "$className" | sort -u | head -7 之类的东西?
  • 不循环直接尝试:grep 'private' ${className} | uniq
  • 我想做的是将像``` $firstname,... ``` 这样的每个变量放在一行中,然后删除私有属性和分号以仅获取变量名称“名字”或“电子邮件”......在数组或字符串中

标签: bash for-loop grep offset


【解决方案1】:

一个简单的班轮就可以了。这也会产生相同的结果:

nbOfMatches=4;grep -m$nbOfMatches private $className

还可以使用 sed 打印 $ ... ; 之间的字符串。 sed 's/.* $\(.*\);/\1/'

nbOfMatches=4;grep -m$nbOfMatches private $className | sed 's/.* $\(.*\);/\1/'

下面是一个冗长的解决方案(如果循环是强制性的)。有很多优雅的方法可以达到相同的结果。

className="input.txt"; nbOfMatches=4; count=0; for next in `cat $className`; do var=$(echo $next | awk /private/'{print $0}'); if [ $nbOfMatches -eq $count ]; then break; fi; if [ ! -z "$var" ]; then echo "$var"; let count=$((count + 1)); fi; done

这会逐行读取指定文件$className 并搜索模式private。对于每个匹配,它将增加变量count。当count 变为需要的匹配数$nbOfMatches 时,它会退出循环。

也打印$ ... ;之间的字符串。

className="input.txt"; nbOfMatches=4; count=0; for next in `cat $className`; do var=$(echo $next | awk /private/'{print $0}'); if [ $nbOfMatches -eq $count ]; then break; fi; if [ ! -z "$var" ]; then echo "$var"| sed 's/.* $\(.*\);/\1/'; let count=$((count + 1)); fi; done

【讨论】:

    【解决方案2】:

    在一行中获取像$firstname,... 这样的每个变量并删除私有属性和分号以仅获取变量名称“firstname”或“email”...
    当您在私人后始终有一个空间时,您可以使用

    grep 'private ' "$className" | sort -u | sed -rn '1,7 s/private \$([^;]*);/\1/p'
    

    或更短(当文件中的字段是唯一的)

     sed -rn 's/private \$([^;]*);/\1/p' "$className" | head -7
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多