0

我正在编写一个 greps 的 shell 脚本,$foo然后计算出现的次数,然后运行一个命令。每次运行该命令时,该文件中都会少一个 $foo 实例。不确定如何连续读取该文件并减少我设置的变量中的值。

$count= `grep -o $foo /some/file |wc -w`

until [ $count -eq 0 ] 
do
  some_command_that_deletes_foo_in_file
done

但是我意识到这$count是在运行时设置一次并且没有更新。我想要的是在脚本循环 /some/file 时$count更新到当前计数,/some/file直到有 0 个我正在寻找的短语实例。不确定最好的方法是什么。

4

3 回答 3

4

除非您有没有向我们展示的附加代码,否则您$count实际上不需要计算出现次数;您只需要知道字符串是否出现在文件中。为此,您可以编写:

while grep -q -- "$foo" /some/file ; do
  some_command_that_deletes_foo_in_file
done

(使用在grep找到值时返回成功,在没有时返回失败的事实,并使用-q标志来抑制其控制台输出)。

于 2013-10-25T18:17:53.927 回答
0

您只是想删除字符串“$foo”?使用 sed:

sed "/$foo/d" /some/file > /some/other/file

sed命令是一个编辑器。采用/$foo/正则表达式(无论 的值如何$foo),在文件中找到它。d告诉它删除该行。

sed通常不进行就地编辑。您通常必须先写入另一个文件,然后再进行移动。但是,有些sed命令可能有这样的参数。你可以检查你的管理。


第二次尝试

我认为它必须采取一些行动或执行一些处理或某事,其影响之一是 $foos 之一消失了。(但我可能是错的。) – ruakh 昨天

这就是我晚上回答这些问题的结果。

如果它可以找到您的正则表达式,则可以利用grep返回true (即退出值 = 0)的事实,否则返回false(即退出值不等于 0):

while grep -o -q "$foo" "/some/file"
do
    some_command_that_deletes_foo_in_file
done

-q告诉 grep 不要输出任何东西。相反,如果找到字符串,grep则退出值为true ,否则为false

阅读您的联机帮助页grep。有些grep命令没有-q参数。在这种情况下,您需要将 STDOUT 和 STDERR 都重定向到/dev/null.

另一种技巧可能是计算行数,然后将其用作计数器:

count=$(grep -o "$foo" "/some/file" | wc -w)  # $(...) is the preferred syntax over `...`

for loop in {1..$count}
do
    some_command_that_deletes_foo_in_file
done

优点是您只需对文件进行一次 grep 操作(这可能是一个很长的操作)。$foo但是,如果不止一行,您的计数可能不正确。

几点注意事项:

  • $(...)优先于反引号
  • 设置变量时,不要在该变量前面使用美元符号。注意我有count=和没有$count=
  • 观察空间。count= $(...)是错误的,因为等号后面有一个空格。
于 2013-10-25T18:40:25.570 回答
0

您可以在循环中添加 grep 命令:

count=$(grep -o "$foo" /some/file |wc -w)

until (( count == 0 )) 
do
  some_command_that_deletes_foo_in_file
  count=$(grep -o "$foo" /some/file |wc -w)
done
于 2013-10-25T18:13:42.827 回答