【问题标题】:Using brace expansion to move files on the command line使用大括号扩展在命令行上移动文件
【发布时间】:2019-04-25 19:14:47
【问题描述】:

我有一个关于为什么这不起作用的问题。可能,这是一个简单的答案,但我似乎无法弄清楚。

我想移动我拥有的几个文件。它们都有相同的文件名(比如 file1),但它们都在不同的目录中(比如 /tmp/dir1、dir2 和 dir3)。如果我要单独移动这些,我可以按照以下方式做一些事情:

mv /tmp/dir1/file1 /tmp

这行得通。但是,我有多个目录,它们都将出现在同一个位置......而且我不想覆盖。所以,我尝试了这样的事情:

mv /tmp/{dir1,dir2,dir3}/file1 /tmp/file1.{a,b,c}

当我尝试这个时,我得到:

/tmp/file1.c 不是目录

只是为了澄清......这也有效:

mv /tmp/dir1/file1 /tmp/file1.c

很确定这与大括号扩展有关,但不确定原因。

谢谢

【问题讨论】:

  • 你需要使用循环;大括号扩展纯粹是一种捷径,不会让你做任何你不能通过手动输入参数来做的事情。

标签: bash brace-expansion


【解决方案1】:

只需 echo 即可了解 shell 的扩展方式:

$ echo mv /tmp/{dir1,dir2,dir3}/file1 /tmp/file1.{a,b,c}
mv /tmp/dir1/file1 /tmp/dir2/file1 /tmp/dir3/file1 /tmp/file1.a /tmp/file1.b /tmp/file1.c

现在您可以看到您的命令不是您想要的,因为在mv 命令中,目标(目录或文件)是最后一个参数。

【讨论】:

  • 并且任何时候有两个以上的参数,最后一个应该是所有其他参数都应该进入的目录。
【解决方案2】:

不幸的是,这就是 shell 扩展的工作原理。

您可能不得不使用关联数组。

!/bin/bash

declare -A MAP=( [dir1]=a [dir2]=b [dir3]=c )

for ext in "${!MAP[@]}"; do
    echo mv "/tmp/$ext/file1" "/tmp/file1.${MAP[$ext]}"
done

运行时会得到以下输出:

mv /tmp/dir2/file1 /tmp/file1.b
mv /tmp/dir3/file1 /tmp/file1.c
mv /tmp/dir1/file1 /tmp/file1.a

与许多其他语言一样,无法保证键顺序。

${!MAP[@]} 返回一个包含所有键的数组,而${MAP[@]} 返回一个包含所有值的数组。


/tmp/{dir1,dir2,dir3}/file1 的语法扩展为 /tmp/dir1/file /tmp/dir2/file /tmp/dir3/file。这类似于* 扩展的工作方式。 shell 不会使用每种可能的组合来执行您的命令,它只是执行命令,但会将您的一个值扩展到所需的数量。

【讨论】:

    【解决方案3】:

    也许你可以用它们来自的实际目录号来区分它们而不是 a/b/c?

    $: for d in 1 2 3
       do echo mv /tmp/dir$d/file1 /tmp/file1.$d
       done
    mv /tmp/dir1/file1 /tmp/file1.1
    mv /tmp/dir2/file1 /tmp/file1.2
    mv /tmp/dir3/file1 /tmp/file1.3
    

    如果满意,请取出echo

    相关点 - 大括号扩展不是通配符。它与磁盘上的内容无关。它只是创建字符串。

    因此,如果您创建一堆以单个字母或数字命名的文件,echo ? 将使用通配符并列出所有文件,但仅列出实际存在的文件。如果有元音文件但没有辅音文件,则只会显示元音。但是——

    如果您说echo {foo,bar,nope},它将输出foo bar nope,无论其中任何或全部是否以文件或目录等形式存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多