我想删除字符串中包含子字符串的所有文件,如果不包含,我想忽略它,所以我使用正则表达式
str=9009
patt=*v[0-9]{3,}*.txt
for i in "${patt}"; do echo "$i"
if ! [[ "$i" =~ $str ]]; then rm "$i" ; fi done
但是我遇到一个错误:
*v[0-9]{3,}*.txt
rm: cannot remove '*v[0-9]{3,}*.txt': No such file or directory
文件名如下:mari_v9009.txt femme_v9009.txt mari_v9010.txt femme_v9010.txt
答案 0 :(得分:3)
<罢工> bash文件名扩展不不使用正则表达式。参见https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion
要查找“ v后跟3个或更多数字后跟.txt”的文件,则必须使用bash的扩展模式匹配。 演示:
.modal{
position: fixed;
z-index: 99999;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
display: none;
background: rgba(0,0,0,0.5);
}
此模式$ shopt -s extglob
$ touch mari_v9009.txt femme_v9009.txt mari_v9010.txt femme_v9010.txt
$ touch foo_v12.txt
$ for f in *v[0-9][0-9]+([0-9]).txt; do echo "$f"; done
femme_v9009.txt
femme_v9010.txt
mari_v9009.txt
mari_v9010.txt
的作用是:
首先,bash执行brace expansion,结果为
for i in *v[0-9]{3,}*.txt
然后,第一个单词for i in *v[0-9]3*.txt *v[0-9]*.txt
不匹配,bash的默认行为是将模式保留为纯字符串。 *v[0-9]3*.txt
试图删除原本名为“ * v [0-9] 3 * .txt”的文件,这给了您“找不到文件的错误”
下一个,第二个单词 rm
被扩展,但是扩展将包含您不想删除的文件。
我错过了问题中的*v[0-9]*.txt
。
尝试:在not
中,[[ ... ]]
和==
运算符是模式匹配运算符,默认情况下启用了扩展globlobing
!=
但是如果可以进入子目录,最好使用keep_pattern='*v[0-9][0-9]+([0-9]).txt'
for file in *; do
if [[ $file != $keep_pattern ]]; then
echo rm "$file"
fi
done
:
find
如果返回您希望删除的文件,请将find . -regextype posix-extended '!' -regex '.*v[0-9]{3,}\.txt' -print
# ...............................^^^
更改为-print
答案 1 :(得分:1)
您需要删除for
循环中的引号。然后将解释文件名文件:
for i in ${patt}; do echo "$i"
答案 2 :(得分:0)
我假设您正在使用Python。
我已经测试了您的正则表达式代码,发现不需要*
字符。
以下似乎很好用:v[0-9]{3,}.txt
您能详细说明一下这个问题吗?
谢谢,
布伦。
答案 3 :(得分:0)
我只是将错误消息通过管道传递到/ dev / null。这对我有用:
#!/bin/bash
str=9009
patt=*v[0-9]{3,}*.txt
rm $(eval ls $patt 2> /dev/null | grep $str)
答案 4 :(得分:0)
这不是正则表达式,这是问题。看一下扩展的内容:
# echo *v[0-9]{3,}*.txt
*v[0-9]3*.txt femme_v9009.txt femme_v9010.txt mari_v9009.txt mari_v9010.txt
*v[0-9]3*.txt
很明显不存在。您能否阐明要使用{3,}
实现的文件?否则,将其保留下来,它将与您指定的文件名类型匹配。