我有一个requirements.txt
文件,其中包含以下几行-
PyMySQL==0.9.3
botocore==1.12.196
boto3==1.9.188
我需要使用bash就地编辑此文件,以删除包含boto3
和botocore
的所有行。到目前为止,我已经提出了-
while read a ; do echo ${a//boto3==1.9.188/} ; done < requirements.txt > requirements.txt.t ; mv requirements.txt{.t,}
..成功删除了包含boto3==1.9.188
的行。但是,此版本号可以是任何数字,例如1.10.122
。
如何概括上面的脚本以删除包含boto3
和botocore
字符串的所有行?还是有更好的方法来做到这一点?谢谢。
答案 0 :(得分:2)
grep -vE '^(botocore|boto3)\W' requirements.txt > requirements.txt.new && \
mv requirements.txt.new requirements.txt
说明:
-v
告诉grep匹配不匹配模式的输出行,并跳过匹配匹配的行。-E
告诉grep允许使用扩展的正则表达式,我们将其用于替换。^
将样式锚定到行的开头,以使其与foobotocore==1.2.3
不匹配。(x|y)
构造与x
或y
匹配。 (要添加第三个包,只需添加另一个|
即可创建(x|y|z)
。)\W
匹配“非单词字符”,因此模式不匹配botocorefoo==1.2.3
。&&
仅在mv
成功并且至少匹配一行(防止破坏整个文件)时才调用grep
命令。答案 1 :(得分:2)
使用awk
awk '!/(botocore|boto3)/' requirements.txt > requirements.txt.t && mv requirements.txt.t requirements.txt
答案 2 :(得分:1)
使用ed
:
printf 'g/botocore/d\ng/boto3/d\nwq\n' | ed requirements.txt
ed
的工作方式是从标准输入中读取一组命令(由换行符终止),并将它们应用于以其参数命名的文件。如果您熟悉sed
,这些命令应该看起来很熟悉(实际上,sed
是基于ed
的 s tream ed 监视器)。
g/botocore/d
选择与正则表达式botocore
匹配的每一行,并将d
(删除)命令应用于每行。g/boto3/d
对于与boto3
匹配的行执行相同的操作。wq
保存更改和报价。答案 3 :(得分:0)
使用perl:
在这种情况下,我喜欢perl,因为
命令:
$ perl -ni -e '/\b(boto3|botocore)\b/ || print;' requirements.txt
选项分解
/ \ b(boto3 | botocore)\ b / ||打印;
如果行与boto3或botocore的单词不匹配,则进行读取,然后打印。 \ b表示单词边界。
示例:
$ cat requirements.txt
PyMySQL==0.9.3
botocore==1.12.196
boto3==1.9.188
$ perl -ni -e '/\b(boto3|botocore)\b/ || print;' requirements.txt
$ cat requirements.txt
PyMySQL==0.9.3
$
示例备份名为“ requirements.txt.orig”的文件
$ cat requirements.txt
PyMySQL==0.9.3
botocore==1.12.196
boto3==1.9.188
$ perl -ni.orig -e '/\b(boto3|botocore)\b/ || print;' requirements.txt
$ cat requirements.txt
PyMySQL==0.9.3
$ cat requirements.txt.orig
PyMySQL==0.9.3
botocore==1.12.196
boto3==1.9.188