所以,如果我在我的主目录下,我想把foo.c移动到~/bar/baz/foo.c,但是这些目录不存在,有没有什么方法可以自动创建这些目录,这样你只需要输入

mv foo.c ~/bar/baz/ 

一切都会解决的吗?似乎可以将mv别名为一个简单的bash脚本,该脚本将检查这些目录是否存在,如果不存在,将调用mkdir,然后调用mv,但我想检查一下,看看是否有人有更好的主意。


当前回答

你可以使用mkdir:

mkdir -p ~/bar/baz/ && \
mv foo.c ~/bar/baz/

一个简单的脚本自动完成(未经测试):

#!/bin/sh

# Grab the last argument (argument number $#)    
eval LAST_ARG=\$$#

# Strip the filename (if it exists) from the destination, getting the directory
DIR_NAME=`echo $2 | sed -e 's_/[^/]*$__'`

# Move to the directory, making the directory if necessary
mkdir -p "$DIR_NAME" || exit
mv "$@"

其他回答

更傻,但有效的方式:

mkdir -p $2
rmdir $2
mv $1 $2

使mkdir -p目录包含一个共享目标文件名的临时目录,然后使用简单的rmdir删除该文件名目录,然后将文件移动到其新目标。 我认为使用dirname回答可能是最好的。

我在linux上用install命令完成了这一点:

root@logstash:# myfile=bash_history.log.2021-02-04.gz ; install -v -p -D $myfile /tmp/a/b/$myfile

bash_history.log.2021-02-04.gz -> /tmp/a/b/bash_history.log.2021-02-04.gz

唯一的缺点是文件权限被改变了:

root@logstash:# ls -lh /tmp/a/b/

-rwxr-xr-x 1 root root 914 Fev  4 09:11 bash_history.log.2021-02-04.gz

如果你不介意重置权限,你可以使用:

-g, --group=GROUP   set group ownership, instead of process' current group
-m, --mode=MODE     set permission mode (as in chmod), instead of rwxr-xr-x
-o, --owner=OWNER   set ownership (super-user only)

Rsync命令只能在目标路径的最后一个目录不存在的情况下才能实现,例如,对于目标路径~/bar/baz/,如果bar存在而baz不存在,则可以使用以下命令:

Rsync -av——remove-source-files foo.c ~/bar/baz/

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
--remove-source-files   sender removes synchronized files (non-dir)

在这种情况下,如果baz目录不存在,将创建它。但如果bar和baz都不存在,rsync将失败:

sending incremental file list
rsync: mkdir "/root/bar/baz" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(657) [Receiver=3.1.2]

所以基本上使用rsync -av——remove-source-files作为mv的别名应该是安全的。

也许是下面的shell脚本?

#!/bin/sh
if [[ -e $1 ]]
then
  if [[ ! -d $2 ]]
  then
    mkdir --parents $2
  fi
fi
mv $1 $2

这是最基本的部分。你可能想要添加一些来检查参数,如果目标目录存在,或者源目录存在,或者不存在(即不要覆盖不存在的东西),你可能想要改变行为。

代码:

if [[ -e $1 && ! -e $2 ]]; then
   mkdir --parents --verbose -- "$(dirname -- "$2")"
fi
mv --verbose -- "$1" "$2"

例子:

参数:"d1" "d2/sub"

mkdir: created directory 'd2'
renamed 'd1' -> 'd2/sub'