mkdir-p для файлов

Свериться lsof видеть, существуют ли файлы, сохраненные открытыми. Пространство не будет освобождено, пока они не будут закрыты.

sudo /usr/sbin/lsof | grep deleted

скажет Вам, которые удалили файлы, все еще считаются открытыми.

24
31.01.2013, 01:04
7 ответов

Установка сделает это, если дали исходный файл /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, например) как источник.

29
27.01.2020, 19:41

Нет, это не делает насколько я знаю. Но можно всегда использовать mkdir -p и touch друг после друга:

f="/a/b/c.txt"
mkdir -p -- "${f%/*}" && touch -- "$f"
7
27.01.2020, 19:41
dir=$(dirname "$f")
test -d $dir || mkdir -p "$dir"
0
27.01.2020, 19:41
  • 1
    test не необходим; mkdir -p ничего не делает, если dir уже существует. Даже не возвращает ошибку. –  derobert 30.01.2013, 17:36
  • 2
    И конечно, это только создает каталог. –  a CVn 30.01.2013, 17:40

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

B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"
0
27.01.2020, 19:41

Я часто сталкивался с подобными ситуациями, поэтому я просто написал функцию в своем файле .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'
4
27.01.2020, 19:41

Это можно "подделать".

Сначала немного теории:

Роб Гриффитс в 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 answer, чтобы получить следующее:

$ 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
  • затем мы запускаем команду shell, которая использует комбинатор && для группировки 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
0
27.01.2020, 19:41
mkdir -p parent/child && touch "$_/file.txt"

$_— это параметр оболочки, он расширяется до последнего аргумента предыдущей команды. Пример mkdir test && cd "$_"создаст и cdв каталоге test.

3
19.03.2020, 04:47

Теги

Похожие вопросы