【问题标题】:Why does `ln -s * *.txt` complain that the destination isn't a directory in Linux? [closed]为什么 `ln -s * *.txt` 抱怨目标不是 Linux 中的目录? [关闭]
【发布时间】:2021-02-28 02:55:31
【问题描述】:

我需要对文件夹中的所有文件进行符号链接(不重复),只为符号链接添加扩展名,我可以使用精确的引用而不是通配符吗?

root@os:~/test# touch {a..z}

root@os:~/test# ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

root@os:~/test# ln -s a a.txt

root@os:~/test# ls
a  a.txt  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z

root@os:~/test# ln -s * *.txt
ln: target 'a.txt' is not a directory

【问题讨论】:

  • for i in *; do ln -s "$i" "$i.txt"; done
  • 因为 ln 需要 2 个参数,而您传递了 27 个参数。想想 * 的含义。
  • 输入echo the command line with *.globbings 以查看匹配的内容通常会有所帮助。
  • 请注意,有关 UNIX 工具如何工作的问题属于 Unix & Linux,而不是这里 -- Stack Overflow 仅针对有关编写代码的问题。
  • @CharlesDuffy 我同意,但这是一个千钧一发的电话。如果将其放入脚本中,我想应该没问题。

标签: bash wildcard symlink


【解决方案1】:

通配符扩展到当前目录中与给定模式匹配的所有文件名。在您的情况下,* 匹配 aa.txtb、...、z*.txt 匹配 a.txt,因此扩展后您的命令如下所示:

ln -s a a.txt b c ... z a.txt

这是ln 的第三种形式(参见man 1 ln),它要求它的最后一个参数是一个目录,因此会出现错误。

您可以按照 cmets 中的建议使用 for

【讨论】:

  • 哦,我明白了,所以即使它按照我希望的方式处理,它也会创建 a.txt.txt.txt - 非常感谢@yjay 的解释,没有意识到这一点。抱歉没有发布到正确的位置。
【解决方案2】:

shell 只是将您的 globbing 表达式(星号)扩展为命令的参数。所以 ln 会得到参数 a b c d e f g... 和 *.txt 因为不存在带有 txt 扩展名的文件。 但是 ln 需要两个参数来说明您想要做什么。有关详细信息,请参阅 man ln。

您尝试通过循环完成的工作:

假设你的 shell 是 bash,你可以这样做:

for i in *; do ln -s "${i}" "${i}.txt"; done

请记住,如果再次调用它,所有 txt 链接也将再次符号链接。

如果在脚本中使用该行更好地检查文件是否确实存在,否则将给命令提供通配模式。

类似

for i in *.csv; do
    [ -f "${i}" ]  || continue
   # do something with ${i}
done

【讨论】:

  • 我猜循环对我来说是个问题,因为多次运行它会导致多个符号链接文件,如 a.txt 和 a.txt.txt 和 a.txt.txt.txt 等。 . 并且单个文件上的 ln 只会返回 void 因为它已经存在。
  • 注意stackoverflow.com/help/how-to-answerAnswer Well-Asked Questions 部分,以及其中的最后一个要点(要求问题是关于软件开发的)。
猜你喜欢
  • 2013-05-13
  • 1970-01-01
  • 2021-11-30
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2013-08-28
相关资源
最近更新 更多