用于将特定文件向上一级链接的 shell 脚本
我有一个文件夹,里面有很多文件夹,每个文件夹都包含一个电影文件。 现在我希望能够一次看到所有这些电影(但我必须保留文件夹结构),所以我想将它们全部符号链接到顶级文件夹(Directory Opus 中的平面视图将是这里的位置,但我我在 Mac 上)。 这是我的尝试
for file in */*/*.mov;
do
newname='echo $file | sed "s|[^/]*/[^/]*/||g"';
ln -s $file echo $newname;
done
所以我在第 3 行尝试做的是将路径 foo/bar/spud.mov 转换为 spud.mov,然后在第 4 行执行 ln -s foo/bar/spud.mov spud.mov
但它不起作用,我得到的只是
ln: "s|[^/]/[^/]/||g": 没有这样的文件或目录
我尝试了引号和转义符的各种组合,但没有运气。 sed 表达式可以工作,但我显然用我的变量弄乱了一些东西。
谢谢
I've got a folder that's got a whole lot of folders inside, which each contain a movie file. Now I want to be able to see all these movies at one time (but I have to preserve the folder structure) so I wanted to symlink them all to the top level folder (flat view in Directory Opus would be the go here, but I'm on a mac). Here's my attempt
for file in */*/*.mov;
do
newname='echo $file | sed "s|[^/]*/[^/]*/||g"';
ln -s $file echo $newname;
done
So what I'm trying to do on line 3 is turn the path foo/bar/spud.mov into spud.mov and then on line 4 do ln -s foo/bar/spud.mov spud.mov
But it doesn't work, all I get is
ln: "s|[^/]/[^/]/||g": No such file or directory
I've tried various combinations of quotes and escapes, but with no luck. The sed expression works, but I've obviously mucked up something with my variables.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这将对所有文件夹级别执行相同的操作:
This will do the same for all folder levels:
所有的 echo $file | 是怎么回事? sed 或 awk 的东西,无论如何? basename 就是为此目的而设计的。
但是,实际上,当给定一个目录时 ln 会做同样的事情,所以:
或者一个真正通用的版本,它足够聪明,只根据需要多次调用 ln:
也就是说,在本地目录中,找到名称以结尾的所有内容.mov 不在当前目录中(深度大于 1),用 NULL 分隔输出,并通过管道输入 xargs,它正在寻找 NULL 分隔的输入,并将传递 .mov 。 作为 ln 的参数,位于它在 stdin 上读取的所有参数之后。
What's with all the echo $file | sed or awk stuff, anyways? basename's made for this purpose.
But, really, ln does the same thing when given a directory, so:
Or a really general purpose version that's smart enough to only call ln as many times as needed:
That is, in the local directory, find everything with a name ending in .mov that's not in the current directory (depth is more than 1), separate the output with NULLs, and pipe into xargs, which is looking for NULL-separate input, and will pass . as the argument to ln after all the arguments it read on stdin.
我对如何使用 find 有了更多了解,所以现在我可以在一行中完成:
find 命令中的 -exec 标志可让您在每次找到文件时运行另一个进程。 如上所述放入一对花括号,将文件作为参数提供给该进程。 我花了一段时间才弄清楚转义分号之前需要有一个空格。
I know a bit more about how to use find, so now I can do it in one line:
the -exec flag in the find command lets you run another process every time it finds a file. Put in a pair of curly braces as above to give that process the file as a parameter. Took me a while to work out that there needs to be a space before the escaped semicolon.
Basename 是您想要的,而您的解决方案的问题是引用不当:
Basename is what you want, and the problem with your solution is poor quoting:
嗯,谢谢大家。 这罐子里好像有几条虫子。 看来我正在做的事情虽然不是最好的方法,但如果我使用正确的语法,就会起作用。
但我了解了basename并提高了我对ln的了解,所以我很高兴。
Well thanks everyone. Seems to be a few worms in this can. It seems that what I was doing, while not the best way, would have worked if I'd used the right syntax.
But I've learned about basename and improved my knowledge of ln, so I'm happy.