我有这个用例,我试图从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
我在循环中缺少什么?
答案 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
命令,就好像var
已export
一样。这是为了向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
命令