为从命令“find”收集的多本书创建符号链接

为从命令“find”收集的多本书创建符号链接

我想为从运行find命令搜索到的多本书创建符号链接。

首先,我收集了所有的JS书籍

find ~ -type f -iregex  '.*javascript.*\.pdf' > js_books.md 2>/dev/null

返回 35 本书

../Coding/Books/HTML_Collections/Freeman E.T., Robson E. - Head First HTML5. Programming Building Web Apps with JavaScript - 2011.pdf
../Coding/Books/HTML_Collections/Learning Web Design - A Beginner's Guide to HTML, CSS, JavaScript, and Web Graphics - Jennifer Niederst Robbins - 4th Edition - August 2012.pdf
..

另外将它们复制到目录 js_books

mkdir js_books
find ~ -type f -iregex  '.*javascript.*\.pdf' -print0 -exec cp '{}' js_books

它可以工作,但是多个副本会消耗大量磁盘空间。
所以我删除了这些书并尝试在其中建立符号链接。

find ~ -type f -iregex  '.*javascript.*\.pdf' -print0 -exec ln -s '{}' js_books/'{}' \;

它在 js_books 目录中不返回任何内容。

遇到这样的问题该如何解决呢?

答案1

您的find表达式非常简单,可以使用 bash shell 通配符进行复制:

shopt -s globstar nocaseglob
for book in $HOME/Coding/**/*javascript*.pdf
do
  ln -s "$book" "js_books/$(basename "$book")" 
done

首先,我们告诉 bash 启用不区分大小写的文件名通配,并能够通过 递归子目录**,然后我们循环遍历与“(任何)javascript(任何)pdf”模式匹配的所有文件名。对于每个文件名,我们创建一个到 js_books 的符号链接。

您省略了每个文件名的开头,因此我只是注意到您需要在循环中提供完整路径,for以便该ln命令创建有效的符号链接(或者../在符号链接目标中使用适当数量的前缀)。我将您的替换find ~$HOME/Coding,以防万一您使用不同的起始目录。

答案2

目标js_books/'{}'应该只是js_books。如果是目录的话只是使用与原始文件相同的名称。

这里的问题很可能是 {} 添加了上层目录名称,这会危及该函数。

答案3

一种方法是执行以下操作:

find ~ -type f -iregex  '.*javascript.*\.pdf' -printf %f"*"%h | awk -F* '{ system("ln -s "$2"/"$1" "$2"/js_books/"$1) }'

运行 find 命令并打印文件名,后跟星号,然后是目录路径。通过 awk 运行它,分离文件名和目录,并构建 ln 命令以使用 awk 的系统函数执行。

请注意,这对命令注入是开放的,并且在使用系统运行最终命令之前还可以使用 print 将命令打印到屏幕上。

相关内容