我试图移动特定的文件名一次从一个目录到其他使用单一的命令行。我已经捕获的文件名(不完整的路径)在一个变量如下所示,它可能有100至1000个文件名。
var=“M1.txt,A2.dat,T300.log”
我尝试以下命令其工作mv /home/rrajendr/test1/{M1.txt,A2.dat,T300.log} /home/rrajendr/test 2/
如果参数化mv /home/rrajendr/test1/{"$var”} /home/rrajendr/test 2/,则无法使用相同的方法
Error mv:cannot stat/home/rrajendr/test1/{M1.txt,A2.dat,T300.log}:无此文件或目录
它寻找一个文件名,就像这个“{M1.txt,A2.dat,T300.log}”一样,它没有解释为单个文件名。这里缺少了一些东西,请让我知道
我尝试了以下选项,但没有工作
mv /home/rrajendr/test1/ echo $var
-t /home/rrajendr/test2/
mv /home/rrajendr/test1/{$var}
mv /home/rrajendr/test1/{ echo $var
}
我寻找此选项的原因
1.我的源路径是固定的,我不想定义背靠背与完整的限定符为每个文件名,因为我有100个文件。
1.我不想来回切换到文件目录(cd /home/rrajendr/test1/),因为我正在执行其他操作,如aws cli操作和snow cli命令。
1.我已经在一个变量中存储了100个文件名,如字符串var=“M1.txt,A2.dat,T300.log”
1.不想像python等程序那样,在shell中使用for或while循环,也不使用xargs
1.使用单个命令行启动多个文件移动
3条答案
按热度按时间pqwbnv8z1#
如果你正在创建文件列表,并且知道列表中没有有趣的字符,我会使用
eval
:甚至
注意,brace expansion 在2023年还不是POSIX shell的特性。这只在你的sh是bash或zsh或任何其他支持brace expansion的shell时才有效。
我认为正确的方法是循环或使用
xargs
,这样可以减少中断的机会。为什么要避免这样做呢?移动文件从来都不是瓶颈。zf9nrax12#
在GNU Bash、Z Shell和Korn Shell中,大括号扩展是在变量替换之前完成的。这就是为什么尝试的命令会失败,因为大括号只看到字符串
$var
,而不是分配给它的值。一个简单的解决方法是使用
eval
,但要注意**eval
是邪恶的**(见下文)。通常,当创建一个跟踪文件的变量时,建议使用数组而不是单个变量。在OP的情况下,这将导致以下任何解决方案:
Eval是邪恶的:
disho6za3#
对于包含逗号分隔的文件名列表的变量
var
,您可以执行以下操作:POSIX shell在变量扩展期间执行字拆分。通常,引用变量以避免字拆分是一个很好的做法,但在这里我们可以通过设置
IFS
而不是引用来利用这一点,以便存储在var
中的逗号分隔字符串在扩展时被拆分为多个文件名。通过切换到源目录,我们不需要在文件名中包含它。我们使用
&&
来避免在cd
失败时复制错误的文件。正如Jens所指出的,设置IFS只对以下命令生效,因此我们将它们都 Package 在
{ ... }
中,以便将它们视为&&
列表中的单个元素。我们将
--
传递给mv
,以防var
包含可能被误解为选项的文件名。我们将整个命令行 Package 在
( ... )
中,这样就不必显式地将cd
返回到原始目录。这个问题使用了绝对路径。如果没有,那么在执行
cd
之前,有必要计算目标的绝对路径。例如,如果命令在/home
中运行并使用了相对路径,我们可以这样做: