用于将特定文件向上一级链接的 shell 脚本

发布于 2024-07-27 21:59:48 字数 557 浏览 2 评论 0原文

我有一个文件夹,里面有很多文件夹,每个文件夹都包含一个电影文件。 现在我希望能够一次看到所有这些电影(但我必须保留文件夹结构),所以我想将它们全部符号链接到顶级文件夹(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌︼了一个春 2024-08-03 21:59:48

这将对所有文件夹级别执行相同的操作:


for i in `find . -name "*.mov"`
do
  file=`echo $i | /bin/awk -F'/' '{print $NF}'`
  /bin/ln -s $i $file
done

This will do the same for all folder levels:


for i in `find . -name "*.mov"`
do
  file=`echo $i | /bin/awk -F'/' '{print $NF}'`
  /bin/ln -s $i $file
done
好倦 2024-08-03 21:59:48

所有的 echo $file | 是怎么回事? sed 或 awk 的东西,无论如何? basename 就是为此目的而设计的。

for file in */*/*.mov; do 
  newname=`basename $file1
  ln -s $file $newname;
done

但是,实际上,当给定一个目录时 ln 会做同样的事情,所以:

for file in */*/*.mov; do
  ln -s "$file" .
done

或者一个真正通用的版本,它足够聪明,只根据需要多次调用 ln:

find . -name \*.mov -depth +1 -print0 | xargs -0 -J % ln -s % .

也就是说,在本地目录中,找到名称以结尾的所有内容.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.

for file in */*/*.mov; do 
  newname=`basename $file1
  ln -s $file $newname;
done

But, really, ln does the same thing when given a directory, so:

for file in */*/*.mov; do
  ln -s "$file" .
done

Or a really general purpose version that's smart enough to only call ln as many times as needed:

find . -name \*.mov -depth +1 -print0 | xargs -0 -J % ln -s % .

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.

安静被遗忘 2024-08-03 21:59:48

我对如何使用 find 有了更多了解,所以现在我可以在一行中完成:

find . -name "*.mov" -exec ln -s {} \;

find 命令中的 -exec 标志可让您在每次找到文件时运行另一个进程。 如上所述放入一对花括号,将文件作为参数提供给该进程。 我花了一段时间才弄清楚转义分号之前需要有一个空格。

I know a bit more about how to use find, so now I can do it in one line:

find . -name "*.mov" -exec ln -s {} \;

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.

絕版丫頭 2024-08-03 21:59:48

Basename 是您想要的,而您的解决方案的问题是引用不当:

bash-3.2$ echo $file
foo/bar/spud.mov
bash-3.2$ newname=$(echo $file | sed 's|[^/]*/[^/]*/||g'); echo $newname
spud.mov

Basename is what you want, and the problem with your solution is poor quoting:

bash-3.2$ echo $file
foo/bar/spud.mov
bash-3.2$ newname=$(echo $file | sed 's|[^/]*/[^/]*/||g'); echo $newname
spud.mov
如日中天 2024-08-03 21:59:48

嗯,谢谢大家。 这罐子里好像有几条虫子。 看来我正在做的事情虽然不是最好的方法,但如果我使用正确的语法,就会起作用。

但我了解了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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文