Bash 在对文件进行灰显的for循环和;是否使用文件查询对文件进行灰显?

Bash 在对文件进行灰显的for循环和;是否使用文件查询对文件进行灰显?,bash,shell,loops,grep,text-processing,Bash,Shell,Loops,Grep,Text Processing,我以前有一个像下面这样的脚本 for i in $(cat list.txt) do grep $i sales.txt done 其中cat list.txt tomatoes peppers onions Price Products $8.88 bread $6.75 tomatoes $3.34 fish $5.57 peppers $0.95 beans $4.56 onions 和cat sales.txt tomatoes peppers onions Price Pr

我以前有一个像下面这样的脚本

for i in $(cat list.txt)
do
  grep $i sales.txt
done
其中
cat list.txt

tomatoes
peppers
onions
Price Products
$8.88 bread
$6.75 tomatoes
$3.34 fish
$5.57 peppers
$0.95 beans
$4.56 onions
cat sales.txt

tomatoes
peppers
onions
Price Products
$8.88 bread
$6.75 tomatoes
$3.34 fish
$5.57 peppers
$0.95 beans
$4.56 onions
我是BASH/SHELL的初学者,在阅读了类似的文章后,我将以前的脚本更改为以下内容:

grep -f list.txt sales.txt

这最后一种方法真的比使用for循环更好吗?起初我以为是这样,但后来我意识到这可能是一样的,因为每次grep在目标文件中grep不同的行时,它都必须读取查询文件。有人知道它是否真的更好吗?为什么?如果更好的话,我可能会遗漏一些关于grep如何处理这项任务的信息,但我无法理解。

继续我的评论

您可以通过git下载grep的源代码:

 git clone https://git.savannah.gnu.org/git/grep.git
您可以在src/grep.c的第96行看到一条注释:

/* A list of lineno,filename pairs corresponding to -f FILENAME
   arguments. Since we store the concatenation of all patterns in
   a single array, KEYS, be they from the command line via "-e PAT"
   or read from one or more -f-specified FILENAMES.  Given this
   invocation, grep -f <(seq 5) -f <(seq 2) -f <(seq 3) FILE, there
   will be three entries in LF_PAIR: {1, x} {6, y} {8, z}, where
   x, y and z are just place-holders for shell-generated names.  */
/*与-f filename相对应的行号、文件名对列表
论据。因为我们将所有模式的串联存储在
单个数组、键,可以通过“-e PAT”从命令行获取
或从一个或多个-f-指定的文件名读取。鉴于此

调用,grep-f扩展我的评论

您可以通过git下载grep的源代码:

 git clone https://git.savannah.gnu.org/git/grep.git
您可以在src/grep.c的第96行看到一条注释:

/* A list of lineno,filename pairs corresponding to -f FILENAME
   arguments. Since we store the concatenation of all patterns in
   a single array, KEYS, be they from the command line via "-e PAT"
   or read from one or more -f-specified FILENAMES.  Given this
   invocation, grep -f <(seq 5) -f <(seq 2) -f <(seq 3) FILE, there
   will be three entries in LF_PAIR: {1, x} {6, y} {8, z}, where
   x, y and z are just place-holders for shell-generated names.  */
/*与-f filename相对应的行号、文件名对列表
论据。因为我们将所有模式的串联存储在
单个数组、键,可以通过“-e PAT”从命令行获取
或从一个或多个-f-指定的文件名读取。鉴于此

调用,grep-f您的第二个版本更好,因为:

  • 它只需要对文件进行一次传递(不需要像您所想的那样进行多次传递)
  • 它没有球形和间距错误(您的第一次尝试对于
    绿豆
    /*/*/*/*/*/*
    表现不佳)

  • 当1时,完全可以在shell代码中读取文件。你做对了,2。开销可以忽略不计,但两者都不适用于您的第一个示例(除了文件当前较小的事实)。

    您的第二个版本更好,因为:

  • 它只需要对文件进行一次传递(不需要像您所想的那样进行多次传递)
  • 它没有球形和间距错误(您的第一次尝试对于
    绿豆
    /*/*/*/*/*/*
    表现不佳)

  • 当1时,完全可以在shell代码中读取文件。你做对了,2。开销可以忽略不计,但两者都不适用于您的第一个示例(除了文件当前很小的事实)。

    更易于阅读,循环逻辑写入程序本身,因此几乎肯定更快,只需调用一个程序。。。我想不出有哪种情况下,
    grep-f list.txt sales.txt
    不被认为是“更好”的选择。我想如果您需要在切换
    list.txt中的模式和grepping之间进行一些中间处理,那么可能需要一个循环,具体取决于它是什么。。。也许…它更容易阅读,循环逻辑被写入程序本身,因此它几乎肯定更快,只需调用单个程序。。。我想不出有哪种情况下,
    grep-f list.txt sales.txt
    不被认为是“更好”的选择。我想如果您需要在切换
    list.txt中的模式和grepping之间进行一些中间处理,那么可能需要一个循环,具体取决于它是什么。。。也许…我们节省的时间更可能来自于使用单个文件传递执行单个执行,而不是因为C以比Bash更快的速度迭代一个小数组。这正是我想要的解释。我不认为GRIP在C中工作,这会使它比通过文件的纯BASH搜索更有优势。这是有道理的,谢谢。节省我们的时间更可能来自于使用单个文件传递执行单个执行,而不是因为C以比Bash更快的速度迭代一个小数组。这正是我想要的解释。我不认为GRIP在C中工作,这会使它比通过文件的纯BASH搜索更有优势。这是有道理的,谢谢。