我想为从运行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 将命令打印到屏幕上。