我有一个问题,为什么这不起作用。可能是一个简单的答案,但是我似乎无法弄清楚。
我想移动几个文件。它们都具有相同的文件名(比方说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
可以肯定,这与括号扩展有关,但不确定为什么。
谢谢
答案 0 :(得分:2)
只需执行echo
即可了解外壳如何扩展:
$ 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
命令中,目的地(目录或文件)是最后一个参数。
答案 1 :(得分:0)
不幸的是,这就是外壳扩展的工作原理。
您可能必须使用关联数组。
def get_binary_array(input_array, stock_ticker):
return [1 for thing in input_array if thing == stock_ticker else 0]
运行它会得到以下输出:
!/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不会使用每种可能的组合来执行您的命令,它只是执行命令,而是将您的一个值扩展为所需的数量。
答案 2 :(得分:0)
也许您可以用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
,无论这些文件中是否有任何一个或全部作为文件或目录等存在