2

I am curious whether it is possible to create a directory and file inside this directory with one command, similar to mkdir -p but for a text file and intermediate directory.

I read through the touch manual and found nothing. Neither I could find the answer on unix stackexchange.

Is there any way to do so (perhaps without using other command rather than touch), since it is pretty routine task to initiate a new directory with a file?

  • Why do you need these two actions to be a single command?

    Also, you can write such an utility or a bash script which does this as well. Something akin to mkdir -p "$1" && touch "$1/$2"

    – Artem S. Tashkinov Jul 24 '20 at 10:38
  • Please define command here? If by that, you mean executing an utility, you should be able to do it with zero command as mkdir can be made builtin in zsh. (mkdir -p foo && touch foo/bar) is a compound command and a command in the POSIX shell grammar definition of those for that matters. – Stéphane Chazelas Jul 24 '20 at 10:43
  • Why? Is there a use-case? What do you want the contents of that file to be? Its permissions? – ilkkachu Jul 24 '20 at 11:17
  • Relating https://unix.stackexchange.com/q/9123/117549 – Jeff Schaller Jul 24 '20 at 11:39
  • Thank you all. I am a very beginner, and maybe it is not the optimal way to do it, but usually I create a project folder and initiate it with index.html or something like that, that is, the starting point of my project. I thought it was common, but it might be a my mistake. What I was trying to find is if there was an alternative method to create a file specifying the path and creating the intermediate folders with one command, like with mkdir -p, but probably the solution is doing it with function, as && is no shorter. Don't know whether I'll use a function, but thank you anyway! – ryabchenko-a Jul 24 '20 at 12:01
  • Dear Jeff, thank you for your response. Yes, this answers my question, however I wanted to know if there are any other ways to solve the same problem, i.e. if there's a one-liner like above mentioned mkdir -p, but for files. Therefore, I created this post anyways. – ryabchenko-a Jul 24 '20 at 13:41

2 Answers2

2

There's the install command from GNU coreutils with the -D option which can copy a file and create the directories leading to them in one go (and also let you specify the ownership and permissions). By default, it creates executable files and doesn't honour the umask as it's typically used as a dev tool in make install stages.

install -m u=rw,go=r -D /dev/null some/new/file

(the permissions of the directory components it creates are always u=rwx,go=rx).

Or you could always implement it as a create Zsh function such as:

create() {
  local file ret=0
  for file do
    mkdir -p -- "$file:h" && true >> "$file" || ret=$?
  done
  return "$ret"
}

Though creating an empty regular file seems a bit pointless to me.

Generally, you'd do:

mkdir -p some/dir
your-editor some/dir/some-file

To create some-file (the file would be created as soon you save it (with actual content) in your editor).

Or any other command that creates some content like:

some-command > some/dir/some-file
wget -o some/dir/some-file https://example.com/whatever
cp source some/dir/some-file
...etc.
0

Here's what I have,

#!/bin/zsh -

Create a text file

[[ -z $1 ]] && exit 1

file="$1"

mkdir --parents ${file:h}

$EDITOR $file

The command is called ct (create text), so I run it like: ct path/to/dir/file.txt.

Unlike other answers in other threads, this doesn't make an unnecessary call to dirname, nor does it use the (arguably) denser syntax of ${file#...} or ${file%...}. It also doesn't need to be a function, since it's not changing the shell.