我试图整理我的照片,由于各种历史原因,这些照片散布在我的系统中。为了使我能够开始执行此任务,我一直在尝试使用命令行来构造包含一个或多个jpg文件的所有目录的列表。我确定我不必担心要寻找其他图像文件格式,但是我必须允许jpg以大写和小写形式出现。
我希望每个目录名称在最终列表中仅出现一次。举个例子,如果我有以下目录,每个目录包含一个或多个jpg或JPG文件...。
~Mike/Pictures
~Mike/Pictures/London/Olympics
~Mike/Pictures/London
~Mike/Pictures/London/Holiday
~Mike/Photos
~Mike/Family History/Swaine
我希望结果只在每个目录中列出一次-不管它可能包含多少图像文件-最好先排序然后写入文件
~Mike/Family History/Swaine
~Mike/Photos
~Mike/Pictures
~Mike/Pictures/London
~Mike/Pictures/London/Holiday
~Mike/Pictures/London/Olympics
我的命令行技能还不满足于此!我可以使用很多简单形式的单个命令,但是一旦它们变得复杂和/或必须通过管道传输,事情就会出错。
假设JPEG图像文件具有后缀.jpg
:
find "$HOME" -type f -name '*.jpg' \
-exec sh -c 'for d; do dirname "$d"; done' sh {} + | sort -u -o jpeg_dirs.txt
这取决于您的目录名称中没有换行符,也没有时髦的目录名称。
使用GNU find
:
find "$HOME" -type f -name '*.jpg' -printf '%h\n' | sort -u -o jpeg_dirs.txt
这些find
命令将在您的主目录下找到所有JPEG图像,并打印找到它们的目录名称。在sort -u
将目录名称的列表,排序,并删除重复。结果将被写入jpeg_dirs.txt
当前目录中的文件。
回顾2021年初(3.3年后)的情况,我有点畏缩,因为我上面的解决方案虽然本身没有错,但还是有些倒退。它还对“好的文件名”做出了明显的假设(没有换行符)。
当您find
用来搜索目录时,请不要像上面那样搜索常规文件;实际搜索目录。找到目录后,我们可以查看其中的每个目录,并查看该文件是否为匹配的文件(*.jpg
或*.JPG
易于添加的其他文件名后缀):
find "$HOME" -type d -exec bash -O nullglob -O dotglob -O extglob -c '
for dirpath do
set -- "$dirpath"/*.@(jpg|JPG)
[[ "$#" -gt 0 ]] && printf "%s\n" "$dirpath"
done' bash {} +
这将从您的主目录向下窥视每个目录,并尝试扩展每个目录中的globing模式*.@(jpg|JPG)
。该模式也可以写成两个单独的模式,*.jpg
和*.JPG
匹配我们要查找的所有文件。如果一个名称匹配,我们假定这是我们要输出名称的目录。对于仅包含具有这些后缀的子目录的目录,这将产生误报。
运行内部bash
脚本时使用的shell选项允许我们匹配隐藏的名称(dotglob
),如果不匹配任何内容而不是保持未展开(nullglob
),则允许通配符模式完全消失,并允许我们使用ksh
-inspired扩展球形模式@(...|...)
。
使用zsh
外壳:
typeset -U list=(~/**/*.(jpg|JPG)(.DN:h))
print -rC1 $list
这将创建一个数组变量,list
其属性是仅存储唯一元素。初始化为扩展文件名遍历模式的结果。该模式匹配主目录中或主目录下的所有JPEG图像文件,并且:h
末尾的会从生成的路径名中删除实际的文件名。在.
使图案只匹配常规文件,并且D
和N
行为像dotglob
和nullglob
在bash
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句