在按回车键之前,我不小心忘记指定目的地。不mv ./*
指定目的地将当前目录下的文件和目录移动到哪里?
小智 42
如果最后一个参数是一个目录,则您只需将当前工作目录中的所有文件和目录(名称以点开头的文件和目录除外)移动到该目录中。如果有两个文件,第一个文件可能覆盖了第二个文件。
以下是一些演示:
两个以上的文件,最后一个参数是一个文件
$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory
Run Code Online (Sandbox Code Playgroud)
两个以上的文件,最后一个参数是一个目录
$ mkdir d1 d2 d3
$ touch a b c
$ mv -v *
'a' -> 'd3/a'
'b' -> 'd3/b'
'c' -> 'd3/c'
'd1' -> 'd3/d1'
'd2' -> 'd3/d2'
Run Code Online (Sandbox Code Playgroud)
两个文件
$ touch a b
$ mv -v *
'a' -> 'b'
Run Code Online (Sandbox Code Playgroud)
进一步说明
shell 将 glob( *
)扩展为 的参数mv
。glob 通常按字母顺序展开。mv
总是看到文件和目录的列表。它永远不会看到 glob 本身。
该命令mv
支持两种类型的移动。一个是mv file ... directory
。另一个是mv old-file-name new-file-name
(或mv old-file-name directory/new-file-name
)。
mik*_*erv 31
首先,我将创建一个测试库 - 5 个文件和一个文件夹:
touch file1 file2 file3 file4 file5
mkdir folder
Run Code Online (Sandbox Code Playgroud)
接下来我将运行一个测试命令。该-v
选项指定我希望 shell 执行的每个命令都打印到stderr
. 该-x
选项指定我希望将相同的内容打印到stderr
-但我希望在评估命令之后但在shell 运行它之前完成它。
sh -cxv 'echo mv *'
Run Code Online (Sandbox Code Playgroud)
echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
Run Code Online (Sandbox Code Playgroud)
所以你看到我提供给 shellecho mv *
的命令是,shell在 *
展开后执行的命令是echo mv
所有这些文件和文件夹。
默认情况下,shell 将展开globs,如:
sh -cxv 'echo file[1-5]'
Run Code Online (Sandbox Code Playgroud)
echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
Run Code Online (Sandbox Code Playgroud)
这是set [+-]f
glob 函数的结果:
sh -cxvf 'echo file[1-5]'
Run Code Online (Sandbox Code Playgroud)
echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
Run Code Online (Sandbox Code Playgroud)
因此,当您在配置了默认选项mv *
的 shell 中运行命令时,例如shell 会扩展为*
当前目录中根据语言环境排序的所有文件的参数列表。它exec(ve)
为mv
(基本上)附加了这个参数列表的系统调用。因此mv
,当 shell 对它们进行 glob 处理并对其进行排序时,会获取所有参数。除了做strace
看看这些效果,你可以再次使用调试出来,如:
sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
Run Code Online (Sandbox Code Playgroud)
sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
Run Code Online (Sandbox Code Playgroud)
并且便携:
( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
Run Code Online (Sandbox Code Playgroud)
: /mv/file1/file2/file3/file4/file5/folder/
Run Code Online (Sandbox Code Playgroud)
基本上,shellmv
使用目录的内容(如果它不为空并且不包括名称以 开头的文件/文件夹.
)作为其参数列表来执行。mv
is POSIX 指定将其最终参数解释为目录,如果它使用两个以上的参数调用 - 以相同的方式ln
is (因为,事实上,它们在底层函数中是非常相似的工具)。
足够了echo
:
sh -cxv 'mv *' ; ls
Run Code Online (Sandbox Code Playgroud)
mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
Run Code Online (Sandbox Code Playgroud)
所有文件都移到最后一个参数中 - 因为它是一个文件夹。现在如果它不是文件夹怎么办?
sh -cxv 'cd *; mv *'; ls . *
Run Code Online (Sandbox Code Playgroud)
cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
Run Code Online (Sandbox Code Playgroud)
这是POSIX 指定 mv
在这种情况下的行为方式:
mv [-if] source_file target_file
mv [-if] source_file... target_dir
Run Code Online (Sandbox Code Playgroud)
在第一种概要形式中,
mv
实用程序应将 source_file 操作数命名的文件移动到target_file指定的目的地。当最终操作数未命名现有目录并且不是引用现有目录的符号链接时,将采用第一种概要形式。在这种情况下,如果source_file命名一个非目录文件并且target_file以尾随/slash
字符结尾,mv
则应将其视为错误并且不会处理source_file操作数。在第二种概要形式中,
mv
应将 source_file 操作数命名的每个文件移动到target_dir操作数命名的现有目录中的目标文件,或者如果target_dir是引用现有目录的符号链接,则引用。每个 source_file 的目标路径应是目标目录的串联,/slash
如果目标不是以 a 结尾,则为单个字符/slash
,以及source_file的最后一个路径名组件。当最终操作数命名现有目录时,采用第二种形式。
所以如果*
扩展为:
两个文件
renamed
第二个之后的第一个到第二个是unlinked
.一个或多个文件,最后是一个目录或一个链接
还要别的吗
jof*_*fel 19
首先,shell 扩展./*
到当前目录中的所有文件(以点开头的文件除外)。
mv
失败mv
失败。