在 Shotwell 中打开图像文件夹(包括子文件夹)

在 Shotwell 中打开图像文件夹(包括子文件夹)

就像是

shotwell *.cr2 ./

这不起作用,但基本上我想使用 shotwell 打开.cr2当前目录中所有以 和 结尾的文件(包括子文件夹)

背景是,我丢失了用相机拍摄的照片,但后来这些照片从我的存储卡上被删除了。

shotwell 的“丢失图片”里有这些图片的缩略图,但我找不到。所以我想我应该跑去photorec试着找找。结果 photorec 给了我一大堆文件夹和文件,多到填满了我的硬盘。我没有一个一个地筛选所有文件,而是决定在我的硬盘上搜索 .cr2 文件,同时避开一个特定的文件夹,Photogs我知道这个文件夹没有这些文件,因为这些文件不是photorec数据转储的一部分。

答案1

通常,您只需打开 Shotwell 并拖入文件夹。

如果需要,您可以让 shell 构建 CR2 文件列表并告诉 Shotwell 只打开这些文件。有时这可能是您想要的,但在这种情况下没有完全满足你的需要由于 Shotwell 的行为 - 在某些其他情况下,一项功能 - 自动向您显示与您打开的图像位于同一文件夹中的其他图像文件(所有类型)。

为了确保 Shotwell 只知道您感兴趣的图像,您可以将目录树克隆到其他地方,只复制.cr2文件和包含它们的文件夹,而不复制其他内容。不过,这可能会占用大量额外空间。因此,另一种方法是构建一个层次结构符号链接-- 而不是拥有新的目录树副本你的原始.cr2文件,你有一个新的目录树syminks 到它们。这样占用的空间就小得多。

这个答案涵盖了所有这些方法。

在 Shotwell 中打开图像文件夹(包括子文件夹)

Shotwell 本身提供了两种打开整个照片目录树的方法。如果这两种方法对你有用,那么你就不需要在命令行中做任何巧妙的事情,甚至根本不需要使用它。如果不行,你最终可能会结合另一种技术来做到这一点。(例如,如果你最终创建了一个包含符号链接或文件副本的新目录.cr2,你可以使用其中一种方法来打开它。)

方法 1:只需在 Shotwell 中打开整个文件夹。

在肖特韦尔,在文件菜单,点击从文件夹导入。然后选择要从中导入图像的文件夹。这不仅限于.cr2文件,但如果您打开包含.cr2数码相机创建的图像的多个子文件夹中的文件,则很可能只有这些文件存在。

Shotwell 文件菜单中从文件夹导入菜单项的屏幕截图。

雅各布的回答递归显示所有图片(包括所有子文件夹)了解更多信息。

方法 2:将文件夹拖入 Shotwell。

使用大多数桌面环境和文件浏览器,您还可以打开 Shotwell 并将包含图像的文件夹拖到 Shotwell 窗口中。例如从文件夹导入,这是Shotwell推荐的另一种打开照片的方式。

我将桌面文件夹拖入 Shotwell 以导入其中包含的图像的屏幕截图。

当您从文件浏览器窗口或桌面拖入 Shotwell 时,您可以拖到特定库。或者,如果您没有设置多个库,您可以直接拖到任何地方,它都可以工作。(您甚至不必拖到左侧窗格。)

这种方法非常方便,并且与手动选择文件夹一样强大(使用文件>从文件夹导入(如上所述)。使用以下方式打开文件或文件夹时这两种方法,Shotwell 让您可以选择打开照片而不将其复制到其图库中。

Shotwell 对话框的屏幕截图,要求用户选择将图像复制到 Shotwell 库的位置,或将其导入到位而不进行任何复制。

要导入但不复制,请单击就地导入代替复制照片


使用图像文件名列表启动 Shotwell

如果由于某种原因您想要或需要通过在终端中运行命令来执行此操作,则可以运行该shotwell命令并将每个图像的文件名作为参数传递给它。全球星使它变得简单:

shopt -s globstar
shotwell **/*.cr2

这将打开.cr2位于当前目录中任意位置的文件。它与运行 Shotwell 然后拖动文件夹不同,Shotwell 只会尝试导入您为其指定名称的文件。但是,由于 Shotwell 经常显示与您指示其打开的文件相同的文件夹中的其他图像文件,因此这可能不能满足您的需求。(并且你提供的有关问题的进一步信息表明,情况并非如此。请参阅下文了解替代方案。)

不包括名称以 开头的文件或子文件夹.。但是,如果你有 CR2 文件,其名称以点开头,那么大多数情况下你可能无论如何都不想在 Shotwell 中打开它们。除非您故意以这种方式命名文件或文件夹,否则带有图像或文档文件扩展名的点文件更可能是元数据文件,而不是实际的图像或文档。例如,macOS 经常添加此类文件(例如,._kittens.cr2对于实际图片kittens.cr2)访问外部媒体(包括闪存驱动器和数码相机)时。

如果你确实想要还可以查找名称以 开头的文件.或名称以 开头的文件夹中的文件.,然后启用 dotglob。您可以使用shopt -s dotglob或通过将globstar和都传递dotglobshopt内置函数来执行此操作:

shopt -s globstar dotglob

默认情况下,globs 区分大小写。但你可能需要不区分大小写地匹配文件名,以便打开以.cr2.Cr2.cR2和结尾的文件.CR2。为此,请执行以下操作之一:

  • 通过运行(单独运行或与其他 shell 选项一起运行)shopt -s来启用 nocaseglob 。例如,要对所有文件运行,不区分大小写地搜索并包括-files 和-directories 中的文件:nocaseglobshotwell.cr2..

    shopt -s globstar dotglob nocaseglob
    shotwell **/*.cr2
    
  • 或者,在 glob 模式本身中使用.[cC][rR]2而不是.cr2。例如,这可以实现与上述相同的效果:

    shopt -s globstar dotglob
    shotwell **/*.[cC][rR]2
    

    请注意,区分大小写与文件和文件夹是否匹配完全无关.。您可以dotglob从上面的示例中删除它们,它们仍然可以不区分大小写。

指定目录不要只使用当前目录,而要将其名称和 a 放在glob/前面**/*.cr2。例如,shotwell用以下命令替换上面的命令将打开主目录子目录.cr2中的所有文件:Pictures

shotwell ~/Pictures/**/*.cr2

与使用当前目录的第一个命令不同,无论在哪里运行该命令,您都会告诉 Shotwell 打开相同的文件。

测试

如果你真的必须使用终端来执行此操作,那么我猜这可能是更复杂操作的一部分。如果你愿意,你可以在实际运行这些命令之前通过替换来测试它们shotwellprintf '%s\n'它不是将文件名传递给 Shotwell,而是每行列出一个文件名。例如,在我的计算机上:

ek@Io:~$ printf '%s\n' ~/tmp/**/*.cr2
/home/ek/tmp/another image.cr2
/home/ek/tmp/image.cr2
/home/ek/tmp/some folder/image3.cr2

关闭 Globstar 和其他 Shell 选项

已启用 globstar shell 选项,这就是shopt -s globstar上述命令的作用。如果已启用,则不需要多个命令。并且每个 shell 实例只需设置一次 globstar。

您可以通过运行以下命令关闭 globstar:

shopt -u globstar

你可以查看通过运行以下命令来检查 globstar 是打开还是关闭:

shopt globstar

如果您在脚本中使用 globstar,那么如果同一脚本中后面可能存在未考虑使用 globstar 编写的代码,则应考虑将其关闭。例如,在禁用 globstar**时,按您的意愿编写*通常没有问题,但是如果启用 globstar,则会导致严重问题,因为命令会影响比预期多得多的文件。

类似地,如果您使用了 dotglob 或 nocaseglob 并且想要关闭它们,您可以分别使用shopt -u dotglob和 来实现shopt -u nocaseglob。您还可以传递多个 shell 选项来shopt -u同时取消设置它们。例如,要关闭globstar, dotglob、 和nocaseglob

shopt -u globstar dotglob nocaseglob

与 globstar 相比,由于您忘记打开了 dotglob 或 nocaseglob,您可能犯的严重错误更少。但其他人(包括您在 Ask Ubuntu 等网站上咨询的人)通常会在向您推荐命令时假设 dotglob 和 nocaseglob 已被禁用,除非您另有说明。

有关这些与 glob 相关的 shell 选项的更多信息(以及总体而言),请参阅bash 参考手册. 它们主要涵盖在4.3.2 Shopt 内置. 有关 globstar,另请参阅3.5.8.1 模式匹配. 有关 dotglob,另请参阅3.5.8 文件名扩展


创建新的目录树

因为在你的情况下你似乎真的需要 Shotwell 来展示仅有的 .cr2.cr2文件,在与文件相同的文件夹中有非文件.cr2,Shotwell 中的图像浏览也会自动提供这些文件,看起来您需要一个文件夹,其中不包含除.cr2您尝试打开的文件之外的任何其他图像文件。

按照你的建议移动文件,是一种方法,但我建议复制文件,或者更好的是,制作符号链接到文件(也可以看看福多克), 因为:

  • 如果要在设备之间移动文件,则无论如何都需要复制,因此在这种情况下移动速度并不会更快。
  • 如果您有足够的空间,最好保留一个未修改的文件夹,其中包含您开始使用的所有内容,直到您满意所做的操作符合您的需求。显然,这并不总是适用或实用的。但就您而言,这些文件是数据恢复操作的结果。保留一份易于阅读的记录,准确记录从何处恢复了哪些内容可能会很有用。
  • 如果您选择创建符号链接,消耗的额外空间极小. (如果目标磁盘是全满但是,您仍然需要释放其上的空间 - 或者使用不同的目标磁盘 - 来创建符号链接。)

你还需要做另一个决定。你是否在同一目录中创建所有新条目(无论是副本还是符号链接),压扁文件层次结构?或者您是否在目标位置创建与源位置的每个目录相对应的目录,这些目录至少包含一个.cr2文件?

  • 扁平化文件层次结构可让您轻松一次性查看所有文件。特别是,您可以轻松一次性查看所有文件的名称和大小,以及在图形文件浏览器中选择任意文件组合。

  • 但它也会丢失有关它们所在文件夹的信息,这些信息可能很有价值(尽管如果您不移动文件,您可以返回原始文件夹并在那里查找它们)。

  • 然而,扁平化文件层次结构的更大问题是,如果你有不同位置有两个或多个同名文件。如果你扁平化文件层次结构,那么根据你如何操作,除了第一个之外的所有文件都将无法复制(或链接),并且你会收到错误或警告,或者除了最后一个副本(或链接)之外的所有文件都将覆盖

    这是我建议复制或创建符号链接而不是移动文件的另一个原因。如果您“成功”将多个文件移动到同一个文件中,则除了最后一个文件之外,其他所有文件都丢失了!

由于将所有内容平铺到没有子目录的单个目录中存在缺点,因此我在这里采用的方法建立新的目录树到达目的地。

方法一:复制

我首先介绍这种方法,因为它比较简单,但我建议您改为创建符号链接(“方法 2”),特别是当目标驱动器可能没有足够的空间来容纳所有文件时。“方法 2”稍微复杂一些,但更详细,因为关于如何使用该技术的资源似乎较少,我认为大多数处于这种情况的人会更喜欢这种方法,并且适用于这两种方法的信息(关于转义路径中的空格的基本建议)在那里而不是这里给出。

当你需要复制目录树,并且需要自定义复制操作时,通常应该使用rsync代替cp。这就是其中一个例子。

将其替换src为包含所有 CR2 文件的顶级目录的路径,并将其替换dest为要创建的包含 CR2 文件的符号链接层次结构的目录的名称,然后运行:

rsync -rl --prune-empty-dirs --include='*/' --include='*.cr2' --exclude='*' src/ dest

不要忘记/源目录名称后面的除非你想在里面创建一个额外的顶级目录dest也就是说,如果你省略结尾的/,那么rsync将为你创建目标目录,在里面dest。例如,假设src是不包含 的相对路径/。然后:

  • 使用src/您的命令,您将获得该文件的rsync符号链接。dest/foo/bar.cr2src/foo/bar.cr2
  • src在您的命令中,您将获得该文件的rsync符号链接。dest/src/foo/bar.cr2src/foo/bar.cr2

.cr2由于放置符号链接的顶级目录与包含符号链接指向的文件的顶级目录同名可能会造成混淆,因此我建议您/在命令中的目标目录名称末尾包含rsync。(并且,对于源目录,请为其提供一个空的、不存在的或专门用于此目的的目录。否则,您将弄乱其他文件夹。)

通常情况下,当你将文件或目录的名称传递给命令行程序或脚本时,如果目标目录或源目录路径包含任何空格(或 shell 特殊处理的字符,如\$'和其他各种标点符号),那么你必须引用他们。我在“方法 2”中详细介绍了如何针对最常见的空格情况执行此操作 - 该部分中有关引用的建议也适用于此处。但是,如果您不确定如何引用文件夹的名称,您可以让 Ubuntu 为您执行此操作,只需将文件夹拖到 Temrminal 中即可;其完整路径将与正确的引文一起粘贴

复制文件.cr2及其包含的文件夹后,您可以在 Shotwell 中打开目标文件夹。(参见“在 Shotwell 中打开图像文件夹(包括子文件夹)”以上。)但是,在运行之前rsync,我建议您决定是否要跳过以 开头的条目.,以及是否要包含带有大小写变体后缀的条目。如果是这样,您必须运行一些略有不同的rsync命令。

自定义点分条目和区分大小写的处理

您可能需要使用不同的rsync命令来更改是否跳过以点开头的文件和目录,以及是否要在匹配后缀时区分大小写.cr2

上面的命令包括名称以 开头的目录和文件.要排除此类文件和目录,请将 和 放在--exclude='.*/' --exclude='.*'所有其他--includes 和--excludes 之前。也就是说,使用此rsync命令(使用适当的替换srcdest, 当然):

rsync -rl --prune-empty-dirs --exclude='.*/' --exclude='.*' --include='*/' --include='*.cr2' --exclude='*' src/ dest

rsync到目前为止显示的命令都是区分大小写的并且不会复制以.CR2.Cr2.cR2结尾的文件.cr2。如果您想要复制此类文件,则需要通过使用--include模式*.[cC][rR]2代替 来解决这个问题*.cr2

第三个命令是不区分大小写并且(像第一个命令一样)不是跳过名称以 开头的文件和目录.

rsync -rl --prune-empty-dirs --include='*/' --include='*.[cC][rR]2' --exclude='*' src/ dest

如果你采用使用 复制文件的方法rsync,但不确定要使用以下哪个命令,我建议使用那个如果你想确保不遗漏任何内容。但是,你应该知道点文件可能包含元数据,并且名为图像的点文件可能不是真正的图像。请参阅“使用图像文件名列表启动 Shotwell”请参见上面的部分,以及下面“方法 2”中的点文件和区分大小写部分。

第四条命令是不区分大小写和(与第二条命令类似)跳过名称以 开头的文件和目录.

rsync -rl --prune-empty-dirs --exclude='.*/' --exclude='.*' --include='*/' --include='*.[cC][rR]2' --exclude='*' src/ dest

方法 2:创建符号链接

这是我推荐你做的,但如果目标驱动器上有足够的空间,方法 1 也是可以的。你不必阅读方法 1 就可以使用它。

这里介绍的方法会列出文件列表.cr2并循环遍历该列表,根据需要创建目标目录并用每个.cr2文件的符号链接填充它们。

这已经够复杂了,我建议将其放入脚本中,而不是直接以交互方式输入。您可以将脚本放在任何您喜欢的地方,但为了方便起见,我将展示如何将脚本直接放在您的主文件夹中。

编写(或粘贴)脚本。

创建一个文本文件,make-symlinks,位于您的主文件夹中。无需文件扩展名。

您可以使用任何文本编辑器(如 Vim、Nano、Gedit 或 Leafpad)执行此操作。但不要使用 LibreOffice Writer 之类的文字处理器。(如果您愿意,您甚至可以运行cat > ~/make-symlinks,粘贴文件内容,然后在新行上按Ctrl+来完成此操作D。)

如果您将脚本命名为 以外的其他名称make-symlinks,请确保在稍后运行使用该脚本的命令时使用该名称。

#!/bin/bash

shopt -s globstar dotglob nocaseglob

for f in **/*.cr2; do
    mkdir -p "$1/$(dirname "$f")"
    ln -s "$PWD/$f" "$1/$f"
done

将其放入文件中,然后保存文件。此脚本使用 globstar,这是上文中解释的 Bash 功能“使用图像文件名列表启动 Shotwell”

您可以更改它处理点状条目和区分大小写的方式。

根据您的需要,您可能需要进行一些更改:

  • 如果您不想包含.cr2名称以 开头的文件.或位于名称以 开头的目录中的文件.,请dotglob从该shopt行中删除。

    名称以 开头的文件和目录.通常用于元数据(请参阅“使用图像文件名列表启动 Shotwell”部分)。另一方面,如果你想确保你拥有一切,或者如果莫名其妙地缺少了某些你很确定存在的东西,那么应该保留dotglob

  • 如果你只想包含以.cr2但结尾的文件不是案例变体(.CR2.Cr2.cR2),则应删除nocaseglob。由于您的情况涉及数据恢复和Shotwell 不会向你显示你错过的任何文件当您打开符号链接目录时 — — 毕竟,这是此方法的重点 — — 您很可能希望保留nocaseglob

使其可执行。

运行此命令将您的脚本标记为可执行:

chmod +x ~/make-symlinks

在源处运行它并将目标作为参数传递。

然后将目录更改为源目录,即包含图片的顶级文件夹。例如,如果它们位于Pictures主目录的子目录中,则您将运行:

cd ~/Pictures

这是您将运行脚本的地方。将目标目录作为命令行参数传递给脚本。

例如,如果您想要cr2s在桌面上创建一个名为的目录来包含符号链接,请运行:

~/make-symlinks ~/Desktop/cr2s

或者,如果您只是希望将该目录直接放在您的主文件夹中:

~/make-symlinks ~/cr2s

或者,如果您已经安装了一个驱动器/media/you/MyDrive,并且想要在其上创建一个名为的文件夹links来包含符号链接:

~/make-symlinks /media/you/MyDrive/links

但是如果驱动器是/media/you/My Drive(带空格),那么您必须使用引号。以下任何一种都可以(只使用一种,不要全部运行):

~/make-symlinks '/media/you/My Drive/links'
~/make-symlinks /media/you/'My Drive'/links
~/make-symlinks /media/you/My\ Drive/links

但是如果你使用~它作为你的主目录,请不要引用:

~/make-symlinks ~/'Two Words'   # good
~/make-symlinks ~/Two\ Words    # good
~/make-symlinks '~/Two Words'   # BAD, because ~ doesn't get expanded

make-symlinks如果目标目录尚不存在,则为您创建目标目录,就像在其中创建子目录一样。但是,如果目标已存在,它仍可工作。

您甚至可以多次运行它并传递相同的目标目录(例如,如果您使用Ctrl+中断它C),但您会收到failed to create symbolic link已存在的符号链接的错误,这可能会造成混淆。

您可能不想将已存在且包含不相关文件(如您的主目录)的目录名称传递给make-symlinks。如果这样做,您可能会在其中创建一大堆符号链接和子文件夹。您可能希望为 . 使用新目录(或尚不存在的目录)make-symlinks

将新创建的符号链接树导入 Shotwell。

运行后make-symlinks,只需使用本答案第一部分中给出的任一方法将传递给它的目录导入 Shotwell 即可(“在 Shotwell 中打开图像文件夹(包括子文件夹)”)。例如,您可以打开 Shotwell 并将文件夹拖入。

由于文件夹中的所有条目都是指向.cr2文件或包含它们的目录的符号链接,没有其他文件类型,因此 Shotwell 不应该看到任何其他文件。

答案2

Shotwell 会循环显示每个打开了图像的目录中的所有图像,因此find -name '*.cr2' -exec shotwell '{}' +我最初建议的使用方法并没有太大帮助。由于 Shotwell 的设置相当有限,我能想到的唯一打开所需文件的方法就是将文件移动到新目录中。

您可以使用find

mkdir ~/cr2files
find -type f -iname '*.cr2' -not -path './dir/*' -exec cp -v -- '{}' ~/cr2files \;

如果您想避免创建重复文件,请替换cp为。mv

笔记:

  • mkdir ~/cr2files在你的主目录中创建新目录
  • find从当前目录向下递归搜索树
  • -type f仅搜索文件
  • -iname按名称搜索文件,忽略大小写
  • '*.cr2'.cr2- 结尾的名称使用引号阻止 shell 在将 glob 传递给find
  • -not -path './dir/*'dir将从结果中排除目录的内容
  • {}表示找到的文件的路径
  • --aftercp表示cp不接受任何进一步的选项,这可以避免任何以 开头的文件名导致-问题

然后,您可以使用 Shotwell 打开新目录中的任何文件并循环浏览所有文件

答案3

选项 1 -xargs当文件名包含空格时使用

正如下面的评论所指出的,当文件名包含空格时,使用(下面的选项 3)将会中断。使用命令并将输出传递给使用选项back ticks的更安全方法如下所示:findshotwellxargs

find . -name "*.cr2" -print0 | xargs -0 shotwell

-print0标志告诉 find 在文件名之间使用\0(空字符)分隔符,并且该-0标志告诉xargs期望这些\0分隔符。

感谢这里的优秀答案(如何通过管道传输 find 命令返回的文件列表) 在 Stack Overflow 上。

选项 2 --exec当文件名包含空格时使用

正如下面的评论指出的那样,该-exec选项还支持包含空格的文件名。下面的其他评论指出,当文件数量超过以下值时,这将中断。如下所示:

find . -name "*.cr2" -exec shotwell {} +

选项 3 - 当文件名没有空格时

在过去,文件名没有空格,长度还没有达到 256 个字符时,这个选项就很好用了。你会发现很多其他网站都提到了这个选项,但是你不应该使用这个选项过去,使用find命令并将输出传递给shotwell是最简单的方法:

shotwell `find . -name "*.cr2"`

这将从当前目录启动find并包括所有子目录:

  • 请注意上面的用法是back tickand 而不是单引号'。使用反引号类似于在$(...)bash 中将 phrase 括起来。
  • 第一个参数.给出find一个起点,即当前目录。您可以传递/home/$USER/Pictures或其他内容来代替.
  • 第二个参数-name告诉 find 搜索文件名(而不是目录)。
  • 此技术适用于所有命令,而不仅仅是shotwell。例如,您可以将其用于catheadtail大多数其他流行的 Linux 命令。

答案4

我不知道 shotwell 甚至打开了原始文件。我确信 digikam 或 darktable 可能会让您获得更多功能。Digikam 附带一些 Kde 组件,是一款非常出色的照片管理器。Darktable 具有非常好的非破坏性编辑功能。

相关内容