mkdir -p
создаст каталог; он также будет создавать родительские каталоги по мере необходимости.
Существует ли аналогичная команда для файлов, которая будет создавать файл и родительские каталоги по мере необходимости?
mkdir -p
создаст каталог; он также будет создавать родительские каталоги по мере необходимости.
Существует ли аналогичная команда для файлов, которая будет создавать файл и родительские каталоги по мере необходимости?
Ответы:
Установка сделает это, если дан исходный файл /dev/null
. -D
Аргумент говорит , чтобы создать все родительские каталоги:
anthony@Zia:~$ install -D /dev/null /tmp/a/b/c
anthony@Zia:~$ ls -l /tmp/a/b/c
-rwxr-xr-x 1 anthony anthony 0 Jan 30 10:31 /tmp/a/b/c
Не уверен, что это ошибка или нет - ее поведение с файлами устройств не упоминается на странице руководства. Вы также можете просто дать ему пустой файл (например, недавно созданный с mktemp
) в качестве источника.
Я часто сталкивался с такой ситуацией, поэтому я просто написал функцию в своем .bashrc
файле. Это выглядит так
function create() {
arg=$1
num_of_dirs=$(grep -o "/" <<< $arg | wc -l)
make_dirs=$(echo $arg | cut -d / -f1-$num_of_dirs)
mkdir -p $make_dirs && touch $arg
}
Итак, когда я хочу создать файл внутри пути несуществующих каталогов, я скажу
create what/is/it # will create dirs 'what' and 'is', with file 'it' inside 'is'
touchp
, какmkdir -p
Я собирался предложить, поскольку он хранит его в одной строке, хотя установка переменной отдельно позволяет вам изменить ее и довольно легко перезапустить команду из истории.
B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"
Можно «подделать».
Роб Гриффитс опубликовал в 2007 году статью под названием « Легко создавать много новых папок» на Macworld.com, в которой он обсуждал использование xargs
команды для чтения списка файлов для создания каталогов с помощью mkdir
.
xargs
способен ссылаться на placeholder
( {}
) с -I
флагом, который содержит значение для каждого передаваемого аргумента xargs
. Вот разница между этим флагом и без него:
$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt
xargs
также может запускать произвольные команды оболочки с sh -c
флагом:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Мы можем объединить эти понятия с mkdir -p
вместо mkdir
и понятия в @ldx «s ответа произвести это:
$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
Эта команда в основном отображает каждое имя файла в списке файлов, разделенных строками, отсекает файловую часть, создает каталоги mkdir -p
и затем touch
указывает имя файла в соответствующем каталоге.
Скажем, например, моя files.txt
выглядит так:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
cat files.txt
производит deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
deeply/nested/foo/bar.js
deeply/nested/baz/fiz.txt
по трубопроводу xargs
-I {}
, xargs
переведем каждый аргумент в свою собственную команду, так что теперь у нас есть:
deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
&&
комбинатор, чтобы сгруппировать 3 команды, которые запускаются последовательно - первая команда сохраняет файл в переменной окружения (которая повторно используется при следующем проходе файла), используя заполнитель, который мы зарегистрировали ранее, поэтому мы теперь имеют:
f=deeply/nested/foo/bar.txt
f=deeply/nested/baz/fiz.txt
mkdir -p
, но нам нужно вырезать имя файла. Достаточно просто, используя '${f%/*}'
:
mkdir -p deeply/nested/foo/
mkdir -p deeply/nested/baz/
f
переменную полностью, когда мы touch
:
touch deeply/nested/foo/bar.txt
touch deeply/nested/baz/fiz.txt
cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'
, которое имеет UUOC, затем вы подразделяетесь на xargs, который подоболочки возвращается в оболочку, когда while read
цикл имеет больше смысла
while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt
. Тот факт, что вы не можете сделать 10-секундный поиск в Интернете для UUOC, также говорит о себе