删除未命名为“today.md”的文件

删除未命名为“today.md”的文件

我的工作目录中有一系列 markdown 文件:

$ ls *.md
csv_reader.md  egrep.md  find.md  found_pdfs.md  osPathSep_help.md  readme.md  smtplib_help.md  today.md

我想删除它们,除了“today.md”

#!/usr/local/bin/bash
for i in ./*.md ; do
    if [[ $i != "today.md" ]]; then
        echo $i
    fi
done

运行它并得到

$ bash bash/remove_files.sh
./csv_reader.md
./egrep.md
./find.md
./found_pdfs.md
./osPathSep_help.md
./readme.md
./smtplib_help.md
./today.md

尽管如此,结构化命令在命令行中并不方便,我如何用更短的命令完成这样的任务

答案1

使用否定匹配(需要shopt -s extglob,但可能已经设置):

rm !(today).md

(可以先使用ls而不是rm检查结果)。

强大的力量extglob,你也可以做

rm !(yesterday|today).md

如果你想保留两个文件。

答案2

find . -maxdepth 1 -name '*.md' ! -name today.md -type f -print

-type f应该只找到当前目录中的所有文件( )(.或者明确地在其中放置一个目录名称)(-maxdepth 1防止以下子目录.md) 以( )结尾-name '*.md',不包括 ( !) 文件today.md

请务必包含单引号,'*.md'这样您的 shell 在执行之前就不会尝试将其扩展到当前目录中的 .md 文件列表find

它将打印要删除的文件列表。改为-print删除-delete它们。

答案3

以上是更好的解决方案,但您的代码无法工作的原因是由于比较。

“./today.md”不等于“today.md”。

答案4

Unix 因具有多种方法来完成相同的简单任务而闻名。有些人喜欢使用sed,但我喜欢grep,所以如果我只是在命令行上输入,我会使用:

rm -i `ls *.md | grep -v '^today.md$'`
  1. ls *.md列出所有名称以.md.
  2. |将结果通过管道传输ls到下一个命令,但作为副作用,会导致ls在多行上列出文件,每行 1 个。
  3. grep -v '^today.md$'回显不完全匹配的行today.md
  4. rm -i然后获取结果(因为命令在反引号内),询问您是否要一一删除它们。当我使用生成的文件列表时,我总是这样做,以防生成器出现问题。您可以在不询问的rm情况下使用-i来删除文件,但这风险更大,而且也不会为您提供已删除文件的列表。

相关内容