我写了一个脚本将一些文件从一个文件夹移动到另一个文件夹,但出现以下错误,我检查了 2 个文件夹并注意到 1 个文件夹有这样的文件,另一个没有这样的文件,但为什么它们都显示“mv无法统计没有这样的文件或目录”
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
129.88.70.226 132.187.230.1 138.96.116.22 155.185.54.250 192.38.109.144 193.136.227.163 193.175.135.61 195.113.161.13 83.230.127.122
130.104.72.200 132.227.62.122 147.83.29.232 156.17.10.52 192.42.43.22 193.137.173.218 193.205.215.74 212.199.61.205
131.130.69.164 132.252.152.194 148.81.140.193 157.181.175.249 192.43.193.71 193.144.21.131 193.226.19.30 212.51.218.235
131.188.44.102 134.151.255.180 152.66.245.162 160.78.253.31 193.1.170.136 193.145.46.243 194.199.68.165 213.73.40.105
131.254.208.10 138.48.3.203 152.81.47.4 192.114.4.3 193.136.166.56 193.166.160.98 194.42.17.124 41.225.7.4
Run Code Online (Sandbox Code Playgroud)
脚本是:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Run Code Online (Sandbox Code Playgroud)
我跑了进去/home/esolve/project/capture/tcp_50x50/。
Mat*_*Mat 37
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
Run Code Online (Sandbox Code Playgroud)
'那里的引号 ( ) 可以防止 shell 进行通配。将*被逐字传递给mv命令,因为它没有找到文件名为从而未能*在指定的目录中。
将此更改为:
mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"
Run Code Online (Sandbox Code Playgroud)
(如果您的目录名称中包含空格,请使用双引号来防止出现问题。*在引号之外。)
但是,您仍然会收到空目录的错误。(同样的原因:如果文件没有找到模式的匹配项,它会将模式本身作为参数传递给命令。)
Sté*_*las 10
您的代码有几个问题:
Run Code Online (Sandbox Code Playgroud)list=`ls dest_folder`
您将ls没有尾随换行符的输出存储到$list. ls输出以换行符分隔的文件名列表。newline与文件名中的任何字符一样有效,因此无法可靠地使用输出。例如ls,包含一个目录的输出a与b包含一个名为a<newline>b.
Run Code Online (Sandbox Code Playgroud)cd dest_folder
您没有检查该命令是否失败。通常,您应该检查命令的退出状态,但对于 来说尤其如此cd,因为其余命令假定您在该新目录中,如果您不在该目录中,则可能会产生严重后果。
Run Code Online (Sandbox Code Playgroud)cwd=`pwd`
POSIX shell 已经在$PWD变量中维护了当前目录的(一个)路径,因此您不需要在此处使用(特别是在一般情况下,因为命令替换会从路径中删除尾随换行符)。此外,pwdmv接受相对路径,因此您无需建立绝对路径。
Run Code Online (Sandbox Code Playgroud)for folder in $list;do
不加引号的变量是shell 中的split+glob运算符。也就是说,变量的内容被拆分(在 中提到的分隔符上$IFS,空格的特殊规则),并且该拆分产生的每个元素都会查找通配符,以便它们可以扩展到匹配文件的列表。
在这里,您确实需要拆分,但仅适用于换行符,并且您不想要通配符,因此您需要禁用它:
IFS='
'; set -f
for folder in $list
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
同样,不加引号的变量是split+glob运算符。在这里,您既不需要,因此需要引用这些变量。
如前所述,通配符仅在未引用时扩展,因此您需要将其*从引号中移出。如果您之前使用 禁用了通配set -f,则需要set +f在调用该命令之前将其恢复。
更好的写法是:
cd dest_folder &&
for folder in */;do
mv -- "${folder}data/"* "$folder"
done
Run Code Online (Sandbox Code Playgroud)
不过有几点说明:
data文件夹中移动隐藏文件。-i选项添加到mv)。*/,我们只循环遍历目录,但这也包括指向目录的符号链接。如果您不愿意,则需要[ -L "${folder%/}" ] && continue在循环内添加一个。*/将扩展到自身,因此您将收到错误消息,mv说它找不到名为*/data/*. 同样,如果任何文件夹中都没有非隐藏文件,您将收到一条that-folder/data/*不存在的错误消息。