Unix - создать путь к папкам и файлу
Я знаю, что вы можете сделать mkdir
для создания каталога и touch
для создания файла, но нет ли способа выполнить обе операции за один раз?
то есть. если я хочу сделать ниже, когда папка other
не существует:
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
Ошибка:
cp: cannot create regular file `/my/other/path/here/cpedthing.txt': No such file or directory
Кто-нибудь придумал функцию в качестве обходного пути для этого?
Ответы
Ответ 1
Используйте &&
для объединения двух команд в одну строку оболочки:
COMMAND1 && COMMAND2
mkdir -p /my/other/path/here/ && touch /my/other/path/here/cpedthing.txt
Примечание. Раньше я рекомендовал использовать ;
для разделения двух команд, но, как указано в @trysis, вероятно, лучше использовать &&
в большинстве ситуаций, потому что в случае COMMAND1
сбой COMMAND2
не будет выполненный либо. (В противном случае это может привести к проблемам, которые вы, возможно, не ожидали.)
Ответ 2
Сначала нужно создать все родительские каталоги.
FILE=./base/data/sounds/effects/camera_click.ogg
mkdir -p "$(dirname "$FILE")" && touch "$FILE"
Если вы хотите стать творческим, вы можете выполнить функцию:
mktouch() {
if [ $# -lt 1 ]; then
echo "Missing argument";
return 1;
fi
for f in "[email protected]"; do
mkdir -p -- "$(dirname -- "$f")"
touch -- "$f"
done
}
И затем используйте его, как и любую другую команду:
mktouch ./base/data/sounds/effects/camera_click.ogg ./some/other/file
Ответ 3
#!/bin/sh
for f in "[email protected]"; do mkdir -p "$(dirname "$f")"; done
touch "[email protected]"
Ответ 4
вы можете сделать это в два этапа:
mkdir -p /my/other/path/here/
touch /my/other/path/here/cpedthing.txt
Ответ 5
Сделайте это с помощью /usr/bin/install:
install -D /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
когда у вас нет исходного файла:
install -D <(echo 1) /my/other/path/here/cpedthing.txt
Ответ 6
if [ ! -d /my/other ]
then
mkdir /my/other/path/here
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
fi
Ответ 7
нет необходимости в операторах if then
...
вы можете сделать это на одной линии usign ;
mkdir -p /my/other/path/here;cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
- или на две строки -
mkdir -p /my/other/path/here
cp /my/long/path/here/thing.txt /my/other/path/here/cpedthing.txt
- -p
предотвращает возврат ошибок, если каталог уже существует (вот что я искал здесь:))
Ответ 8
В специальном (но не редкотом) случае, когда вы пытаетесь воссоздать одну и ту же иерархию каталогов, может быть полезно cp --parents
.
Например, если /my/long
содержит исходные файлы, а my/other
уже существует, вы можете сделать это:
cd /my/long
cp --parents path/here/thing.txt /my/other
Ответ 9
Это то, что я сделал бы:
mkdir -p /my/other/path/here && touch $_/cpredthing.txt
Здесь $_
- это переменная, которая представляет последний аргумент предыдущей команды, которую мы выполнили в строке.
Как всегда, если вы хотите посмотреть, какой может быть результат, вы можете проверить его с помощью команды echo
, например:
echo mkdir -p /code/temp/other/path/here && echo touch $_/cpredthing.txt
Какое значение выводится как:
mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt
В качестве бонуса вы можете сразу написать несколько файлов, используя расширение скобки, например:
mkdir -p /code/temp/other/path/here &&
touch $_/{cpredthing.txt,anotherfile,somescript.sh}
Опять же, полностью проверяемый с помощью echo
:
mkdir -p /code/temp/other/path/here
touch /code/temp/other/path/here/cpredthing.txt /code/temp/other/path/here/anotherfile /code/temp/other/path/here/somescript.sh
Ответ 10
как я видел и тестировал на форуме unix, это решает проблему
ptouch() {
for p in "[email protected]"; do
_dir="$(dirname -- "$p")"
[ -d "$_dir" ] || mkdir -p -- "$_dir"
touch -- "$p"
done
}
Ответ 11
если вы хотите просто с одним только фрагментом параметра:
rm -rf /abs/path/to/file; #prevent cases when old file was a folder
mkdir -p /abs/path/to/file; #make it fist as a dir
rm -rf /abs/path/to/file; #remove the leaf of the dir preserving parents
touch /abs/path/to/file; #create the actual file