In this post we will cover how to use the Linux command line to create a new file in each sub directory, only if that file doesn’t exist. Of course this can be done by hand, but we are all lazy people, right? So why not make the computer earn its keep?
Essentially then, quite a simple thing today, but also one of those little time savers that crop up infrequently, and because of this I often forget how to do this. So I am documenting it for my own future benefit.
This is something of a follow on from my previous post on using JQ and Bash to Parse JSON.
Let’s say I have the following directory structure:
➜ testing-stuff pwd
/tmp/testing-stuff
➜ testing-stuff mkdir aaa bbb ccc
➜ testing-stuff tree .
.
├── aaa
├── bbb
└── ccc
3 directories, 0 files
➜ testing-stuff
Code language: Shell Session (shell)
Very basic then. A temporary directory with three single level nested sub-directories.
Into aaa
, bbb
, and ccc
I want to create a new file called section.md
.
With three sub-directories, it would likely take longer to type out the command to do this using find
(as we will do below) than it would to simply do it using either individual touch
commands or via Nautilus / the GUI.
But in my real case I had 30+ directories, and as above, I’m pretty lazy. Much better to do a one liner and let Linux do the hard work, than for me to waste 60 keystrokes on ctrl + c, ctrl + v.
The Command
As I say, a lot of intro to what is essentially a fairly common and (comparatively) simple Linux one-liner:
find . -type d -exec sh -c 'touch "{}/section.md"' \;
Code language: Shell Session (shell)
After running this, we should have the desired outcome:
➜ testing-stuff tree .
.
├── aaa
│ └── section.md
├── bbb
│ └── section.md
├── ccc
│ └── section.md
└── section.md
Code language: Shell Session (shell)
This won’t overwrite any existing section.md
files that it finds, so it’s safe to run again and again. Or to put it in another, more nerdy way, this particular command is idempotent.
What’s the command actually doing?
This command searches for all directories in the current directory and creates an empty file called “section.md
” in each of those directories.
Here’s a breakdown of the command:
find .
: This starts thefind
command and specifies the current directory as the starting point for the search.-type d
: This option tellsfind
to only return directories (not files or other types of objects).-exec
: This option allows you to execute a command on each result returned byfind
.sh -c 'touch "{}/section.md"'
: This is the command that will be executed on each directory found byfind
. It uses thetouch
command to create an empty file called “section.md
” in the current directory.{}
is a placeholder for the current directory found byfind
.\;
: This is necessary to terminate the-exec
option.
So, when you run this command, it will search for all directories in the current directory and create an empty file called “section.md
” in each of those directories, if it doesn’t already exist.