【问题标题】:Bash script to move screen shots from desktop to folder用于将屏幕截图从桌面移动到文件夹的 Bash 脚本
【发布时间】:2021-04-04 01:26:41
【问题描述】:

我的桌面上有大量屏幕截图(这是保存它们的默认位置),标题格式为“Screen Shot 2020-10-11 at 7.08.12 PM.png”,我想在“屏幕截图”位上使用带有正则表达式的 bash 脚本将任何此类文件从我的桌面移动到我创建的名为“屏幕截图”的文件夹中。

现在,我正在使用 find . -regex Screen*.*?.png,但它不太有效(它提供了 find: Screen Shot 2020-10-11 at 7.11.09 PM.png: unknown primary or operator)。

我也不确定一旦找到所有正确的文件并将它们移动到文件夹中,我什至会如何使用输出。你能以某种方式使用for i in seq 1 100 或类似的东西遍历文件夹中的所有文件吗?

【问题讨论】:

    标签: bash shell mv


    【解决方案1】:

    这里实际上甚至不需要 -regex:

    find . -type f -name 'Screen Shot*png' -maxdepth 1 -exec echo mv "{}" screenshots \;
    

    您可以安全地运行此命令,因为它只会打印 它做什么。删除echo 以实际运行mv

    所有使用的选项都记录在 man find 中,但简而言之:

    -type f 将使find 只查找文件,而不是目录。这 如果您有一个与-name 匹配的目录,这很有用 - 我们没有 想摸摸。

    -maxdepth 1 只会查找同一目录级别中的触发文件 - 它在这里非常有用,因为您可能已经有一些文件 匹配 screenshots 目录中的 -name - 我们想离开 他们一个人。

    -name 接受 shell 模式,而不是正则表达式。我们当然可以在这里使用-regex,但我更喜欢-name,因为这里的shell 模式更短且更易于使用。

    {} 是一个占位符,将被找到的名称替换 文件。

    \; 是一个 literal 分号,转义以防止它被 由以 -exec 指定的命令结束的 shell 解释。

    【讨论】:

    • 做到了!但我真的不明白。为什么-type f,以及Shot*png 是如何工作的——我认为* 只会对一个字符进行正则表达式(为什么我们在这里不需要-regex?)。我也不明白深度选项和exec{} 在这里做什么。我很想知道你是如何想出它的,以及我将来如何自己写这些。谢谢!
    • 非常有帮助,谢谢。我将查看手册页;但是为什么最后要转义分号,“{}”在这里做什么?
    【解决方案2】:

    从表面上看正则表达式(可能是一个错误),您应该在正则表达式周围使用单引号:

    find . -regex 'Screen*.*?.png'
    

    这可以防止外壳扩展它,将其留给find。然后将文件移动到~/screenshots目录(更改名称以匹配您要使用的目录),如果您有GNU mv,您可以使用:

    find . -regex 'Screen*.*?.png' -exec mv -t ~/screenshots {} +
    

    这会执行一个mv 命令将许多文件移动到目标目录,从而减少mv 的执行次数。它可能仍会执行多次,但会比替代方案少得多。

    如果您没有带有(非常有用的)-t 选项的 GNU mv,那么您应该使用:

    find . -regex 'Screen*.*?.png' -exec mv {} ~/screenshots ';'
    

    这将为找到的每个文件执行一个mv 命令,但更便携。

    您遇到的主要问题是外壳将您写入的内容扩展为文件名列表,然后find 不明白您的意思。使用引号可以防止外壳扩展“正则表达式”。您可以在mv 之前的其他命令中添加echo,以查看将执行的操作。

    但是,我不确定您是否知道您的正则表达式匹配什么。目前尚不清楚给出的正则表达式是否是find 的有效正则表达式——尽管它主要用作 PCRE(Perl 兼容)正则表达式。默认情况下,GNU find 使用 GNU Emacs regular expressions,但您可以控制它使用的正则表达式的方言。可用的选项包括 Emacs、POSIX Awk、POSIX 基本正则表达式 (BRE)、POSIX egrep 和 POSIX 扩展正则表达式 (ERE)。它不包括 PCRE。您提供的更像是一个 shell glob,-name 运算符处理通配名称。

    您很可能应该使用-name 运算符,使用如下命令:

    find . -name 'Screen Shot *.png' -exec mv -t ~/screenshots {} +
    

    【讨论】:

    • 它还能做什么?我不清楚这是什么结果,因为控制台上没有打印任何内容。
    • 第一个版本,没有-exec 选项,打印与regex 匹配的文件名。我不确定你是否知道你的正则表达式匹配什么。您很可能应该使用-name 'Screen*.*.png' 甚至-name 'Screen Shot *.png'。但是您遇到的主要问题是外壳将您写入的内容扩展为文件名列表,然后find 不明白您的意思。使用引号可以防止外壳扩展“正则表达式”。您可以在其他命令中添加echo 以查看将执行的内容。
    • 这太好了 - 谢谢!将来学习 bash 实用程序的这些细微差别有什么技巧吗?
    • @oguzismail — 它可能是一个有效的 PCRE 正则表达式,但 find 可能不支持它们。我之前的评论讨论了这个问题。我没有时间将评论整合到我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2010-10-12
    • 2021-06-18
    相关资源
    最近更新 更多