使用变量在 bash 中传递 grep 模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14414324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:18:30  来源:igfitidea点击:

Using a variable to pass grep pattern in bash

arraysbashdesign-patternsgrepifs

提问by user1464409

I am struggling with passing several grep patterns that are contained within a variable. This is the code I have:

我正在努力传递包含在变量中的几个 grep 模式。这是我的代码:

#!/bin/bash
GREP="$(which grep)"
GREP_MY_OPTIONS="-c"
for i in {-2..2}
do
  GREP_MY_OPTIONS+=" -e "$(date --date="$i day" +'%Y-%m-%d')
done
echo $GREP_MY_OPTIONS

IFS=$'\n'
MYARRAY=( $(${GREP} ${GREP_MY_OPTIONS} "/home/user/this path has spaces in it/"*"/abc.xyz" | ${GREP} -v :0$ ) )

This is what I wanted it to do:

这就是我想要它做的:

  • determine/define where grep is
  • assign a variable (GREP_MY_OPTIONS) holding parameters I will pass to grep
  • assign several patterns to GREP_MY_OPTIONS
  • using grep and the patterns I have stored in $GREP_MY_OPTIONS search several files within a path that contains spaces and hold them in an array
  • 确定/定义 grep 在哪里
  • 分配一个变量(GREP_MY_OPTIONS)保存我将传递给grep的参数
  • 将几种模式分配给 GREP_MY_OPTIONS
  • 使用 grep 和我存储在 $GREP_MY_OPTIONS 中的模式在包含空格的路径中搜索多个文件并将它们保存在数组中

When I use "echo $GREP_MY_OPTIONS" it is generating what I expected but when I run the script it fails with an error of:

当我使用“echo $GREP_MY_OPTIONS”时,它会生成我预期的结果,但是当我运行脚本时,它会失败并出现以下错误:

/bin/grep: invalid option -- ' '

/bin/grep: 无效选项 -- ' '

What am I doing wrong? If the path does not have spaces in it everything seems to work fine so I think it is something to do with the IFS but I'm not sure.

我究竟做错了什么?如果路径中没有空格,一切似乎都可以正常工作,所以我认为这与 IFS 有关,但我不确定。

采纳答案by Jonathan Leffler

If you build the GREP_MY_OPTIONS as an array instead of as a simple string, you can get the original outline script to work sensibly:

如果将 GREP_MY_OPTIONS 构建为数组而不是简单的字符串,则可以使原始大纲脚本正常工作:

#!/bin/bash
path="/home/user/this path has spaces in it"
GREP="$(which grep)"
GREP_MY_OPTIONS=("-c")
j=1
for i in {-2..2}
do
    GREP_MY_OPTIONS[$((j++))]="-e"
    GREP_MY_OPTIONS[$((j++))]=$(date --date="$i day" +'%Y-%m-%d')
done

IFS=$'\n'
MYARRAY=( $(${GREP} "${GREP_MY_OPTIONS[@]}" "$path/"*"/abc.xyz" | ${GREP} -v :0$ ) )

I'm not clear why you use GREP="$(which grep)"since you will execute the same grepas if you wrote grepdirectly — unless, I suppose, you have some alias for grep(which is then the problem; don't alias grep).

我不清楚你为什么使用,GREP="$(which grep)"因为你会grepgrep直接写一样执行- 除非,我想,除非你有一些别名grep(这就是问题所在;不要别名grep)。

回答by Rubens

If you want to grepsome content in a set of paths, you can do the following:

如果要grep在一组路径中获取某些内容,可以执行以下操作:

find <directory> -type f -print0 |
    grep "/home/user/this path has spaces in it/\"*\"/abc.xyz" |
    xargs -I {} grep <your_options> -f <patterns> {}

So that <patterns>is a file containing the patterns you want to search for in each file from directory.

所以这<patterns>是一个文件,其中包含您要在每个文件中搜索的模式directory

Considering your answer, this shall do what you want:

考虑到您的回答,这将满足您的需求:

find "/path\ with\ spaces/" -type f | xargs -I {} grep -H -c -e 2013-01-17 {}

From man grep:

来自man grep

   -H, --with-filename
          Print  the  file  name for each match.  This is the default when
          there is more than one file to search.

Since you want to insert the elements into an array, you can do the following:

由于要将元素插入数组,因此可以执行以下操作:

IFS=$'\n'; array=( $(find "/path\ with\ spaces/" -type f -print0 |
    xargs -I {} grep -H -c -e 2013-01-17 "{}") )

And then use the values as:

然后将这些值用作:

echo ${array[0]}
echo ${array[1]}
echo ${array[...]}

When using variables to pass the parameters, use evalto evaluate the entire line. Do the following:

使用变量传递参数时,使用eval对整行求值。请执行下列操作:

parameters="-H -c"
eval "grep ${parameters} file"

回答by Suku

You can do one thing without making things complex:

你可以做一件事而不会使事情变得复杂:

First do a change directory in your script like following:

首先在脚本中更改目录,如下所示:

cd /home/user/this\ path\ has\ spaces\ in\ it/
$ pwd
/home/user/this path has spaces in it

or

或者

$ cd "/home/user/this path has spaces in it/"
$ pwd
/home/user/this path has spaces in it

Then do what ever your want in your script.

然后在脚本中做任何你想做的事情。

$(${GREP} ${GREP_MY_OPTIONS} */abc.xyz)

EDIT:

编辑

[sgeorge@sgeorge-ld stack1]$ ls -l
total 4
drwxr-xr-x 2 sgeorge eng 4096 Jan 19 06:05 test tesd
[sgeorge@sgeorge-ld stack1]$ cat test\ tesd/file 
SUKU
[sgeorge@sgeorge-ld stack1]$ grep SUKU */file
SUKU

EDIT:

编辑

[sgeorge@sgeorge-ld stack1]$ find */* -print | xargs -I {} grep SUKU {}
SUKU