如何在循环中使用两个文件或一个文件进行grep

时间:2018-02-01 23:03:53

标签: awk sed grep

我有这个用例,我试图从s3列出一些键并根据grep命令过滤结果

fileA - abc/def def/123 列出密钥后,我试图从列表中删除这个确切的密钥。例如,如果列表返回2个具有相同前缀的其他键

list - abc/def/123 abc/def/1234 abc/ghi/12345 def/123/456 def/456/4567

我想删除与从文件中读取的模式匹配的密钥,即abc/def and def/123

代码:

while read line; do prefix = $(echo "$line"| grep -oPw '[A-Za-z0-9]*') aws s3api list-objects --bucket blah-bucket --prefix "$prefix" | grep -vFfw "$line" > result done < fileA

我收到command not found : prefix

这个错误

我在循环中缺少什么?

3 个答案:

答案 0 :(得分:1)

这是一个常见的问题,已经在这里发布了多年和多年的各种问题。 : - )

您想要的符号应该更像这样:

prefix="$(echo ...)"

请记住,shell是一个 shell ,而不是一个完全成熟的编程语言。它的解析规则旨在促进调用其他程序,并设置管道以允许这些程序相互交互。

以下是Bourne系列中的shell(sh,bash,ksh,zsh,ash / dash)可以解释错位空间的各种方法。考虑:

var=val
var =val
var= val
var = val
  • var=val:这是变量分配的正确语法 - 一个不带引号的单词,紧跟一个紧跟后面紧跟一个参数。
  • var =val:这会运行var命令并将=val作为参数。
  • var= val:这会为var变量分配一个空字符串,然后运行val命令,就好像varexport一样。这是为了向shell调用的命令提供一次性环境变量。
  • var = val:这会以var=作为参数运行val命令。

其他(非Bourne-style或non-POSIX)shell将有不同的解释。

另外,请注意,对于此循环的每次迭代,您都将覆盖文件result

答案 1 :(得分:1)

嗯,你有简单的语法错误。但是,如果我理解删除与文件中读取的模式相匹配的键的意思,那么你的工作就太难了。

如果以下解决方案符合您的要求,我保证它会更快地运行并且更容易理解:

$ head patterns input
==> patterns <==
abc/def
def/123

==> input <==
abc/def/123
abc/def/1234
abc/ghi/12345
def/123/456
def/456/4567

$ grep -vf patterns input
abc/ghi/12345
def/456/4567

任何迭代数据的shell解决方案都是错误的方法。寻找让 grep 和朋友对整个文件进行操作的方法,并使用shell来选择文件。总是可以安全地确定你的问题可以通过这种方式解决,因为几十年来很多问题看起来像你的问题。 :-)

答案 2 :(得分:1)

您还可以使用以下命令链:

$cat to_remove.in 
abc/def
def/123


$cat to_process.in 
abc/def/123
abc/def/1234
abc/ghi/12345
def/123/456
def/456/4567


$awk 'BEGIN{ORS="\\\\|"}{print}' to_remove.in | sed 's/\\|$//' | xargs -I {} grep -v {} to_process.in
abc/ghi/12345
def/456/4567

<强>说明:

  • awk将用于创建文件to_remove.in的正则表达式,每行之间| grep -v将用于排除文件{{1}中的行}}
  • to_process.in用于删除正则表达式字符串末尾的最后sed 's/\\|$//'
  • 然后使用|将生成的正则表达式字符串传递给xargs命令