Есть ли способ заставить mv создать каталог, который нужно переместить, если он не существует?

Итак, если я в своем домашнем каталоге, и я хочу переместить foo.c в ~/bar/baz/foo.c, но эти каталоги не существуют, есть ли способ автоматически создать эти каталоги, так что вам нужно будет только напечатать

mv foo.c ~/bar/baz/ 

и все будет работать? Похоже, вы могли бы alias mv просто bash script, который бы проверял, существуют ли эти каталоги, и если бы не вызывал mkdir, а затем mv, но я думал, что проверил бы, есть ли у кого-то лучшее представление.

Ответ 1

Как об этом однострочном (в bash):

mkdir --parents ./some/path/; mv yourfile.txt $_

Нарушение этого:

mkdir --parents ./some/path

создает каталог (включая все промежуточные каталоги), после чего:

mv yourfile.txt $_

перемещает файл в этот каталог ($ _ расширяется до последнего аргумента, переданного предыдущей команде оболочки, то есть: вновь созданный каталог).

Я не уверен, насколько это будет работать в других оболочках, но это может дать вам некоторые идеи о том, что искать.

Вот пример использования этого метода:

$ > ls
$ > touch yourfile.txt
$ > ls
yourfile.txt
$ > mkdir --parents ./some/path/; mv yourfile.txt $_
$ > ls -F
some/
$ > ls some/path/
yourfile.txt

Ответ 2

mkdir -p 'dirname /destination/moved_file_name.txt'  
mv /full/path/the/file.txt  /destination/moved_file_name.txt

Ответ 3

Сохранить как script с именем mv или mv.sh

#!/bin/bash
# mv.sh
dir="$2"
tmp="$2"; tmp="${tmp: -1}"
[ "$tmp" != "/" ] && dir="$(dirname "$2")"
[ -a "$dir" ] ||
mkdir -p "$dir" &&
mv "[email protected]"

Или положите в конец вашего файла ~/.bashrc как функцию, которая заменяет значение по умолчанию mv на каждом новом терминале. Использование функции позволяет bash хранить память, а не читать файл script каждый раз.

function mv ()
{
    dir="$2"
    tmp="$2"; tmp="${tmp: -1}"
    [ "$tmp" != "/" ] && dir="$(dirname "$2")"
    [ -a "$dir" ] ||
    mkdir -p "$dir" &&
    mv "[email protected]"
}

Они основаны на представлении Криса Лутца.

Ответ 4

Вы можете использовать mkdir:

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

Простой script для этого автоматически (непроверенный):

#!/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 "[email protected]"

Ответ 5

Следующая оболочка script, возможно?

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

Это основная часть. Возможно, вы захотите добавить немного, чтобы проверить аргументы, и вам может потребоваться, чтобы поведение изменилось, если место назначения существует, или исходный каталог существует или не существует (т.е. Не перезаписывать то, что не существует).

Ответ 6

Похоже, что ответ - нет:). Я действительно не хочу создавать псевдоним или func только для этого, часто потому, что он одноразовый, и я уже в середине ввода команды mv, но нашел что-то, что хорошо работает для этого:

mv *.sh  shell_files/also_with_subdir/ || mkdir -p $_

Если mv сбой (dir не существует), он сделает каталог (который является последним аргументом предыдущей команды, поэтому $_ имеет его). Поэтому просто запустите эту команду, затем up запустите ее, и на этот раз mv должно получиться.

Ответ 7

Сильер, но рабочий путь:

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

Создайте каталог с mkdir -p, включая временный каталог, в котором находится имя целевого файла, затем удалите этот каталог имен файлов с помощью простого rmdir, а затем переместите файл в новый пункт назначения. Я думаю, что ответ с использованием dirname, вероятно, лучший.

Ответ 8

Самый простой способ сделать это:

 mkdir [directorie name] && mv [filename] $_

Предположим, что я загрузил pdf файлы, расположенные в моей директории загрузки (~/download), и я хочу переместить все это в директиву, которая не выйдет (скажем, "my_PDF" ).
Я наберу следующую команду (убедитесь, что моя текущая рабочая директива ~/download):

mkdir my_PDF && mv *.pdf $_

Вы можете добавить опцию -p в mkdir, если вы хотите создавать подкаталоги именно так: (предполагается, что я хочу создать подкаталог с именем "python" ):
mkdir -p my_PDF/python && mv *.pdf $_

Ответ 9

Вы даже можете использовать расширения скобок:

mkdir -p directory{1..3}/subdirectory{1..3}/subsubdirectory{1..2}      
  • который создает 3 каталога (directory1, directory2, directory3),
    • и в каждом из них два подкаталога (подкаталог 1, подкаталог2),
      • и в каждом из них находятся два подкаталога (subsubdirectory1 и subsubdirectory2).

Вы должны использовать bash 3.0 или новее.

Ответ 10

Команда 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.

Ответ 11

$what=/path/to/file;
$dest=/dest/path;

mkdir -p "$(dirname "$dest")";
mv "$what" "$dest"

Ответ 12

Одно однострочное решение:

test -d "/home/newdir/" || mkdir -p "/home/newdir/" && mv /home/test.txt /home/newdir/

Ответ 13

Код:

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'

Ответ 14

Вы можете объединять команды: mkdir ~/bar/baz | mv foo.c ~/bar/baz/ mkdir ~/bar/baz | mv foo.c ~/bar/baz/
или сценарий оболочки здесь:

#!/bin/bash
mkdir $2 | mv $1 $2

1. Откройте любой текстовый редактор
2. Скопируйте и вставьте скрипт оболочки.
3. Сохраните его как mkdir_mv.sh
4. Введите директорию вашего скрипта: cd your/script/directory
5. Измените режим файла: chmod +x mkdir_mv.sh
6. Установите псевдоним: alias mv="./mkdir_mv.sh"
Теперь всякий раз, когда вы запускаете команду mv каталог для перемещения будет создан, если он не существует.

Ответ 15

((cd src-path && tar --remove-files -cf - files-to-move) | ( cd dst-path && tar -xf -))