How to Touch a File and Mkdir If Needed in One Line

How to touch a file and mkdir if needed in one line

In perl, using one of my favorite module: Path::Tiny.

path("/opt/test/test.txt")->touchpath;

From the doc:

Combines mkpath and touch. Creates the parent directory if it doesn't
exist, before touching the file.

is there a touch that can create parent directories like mkdir -p?

There is no touch that can create parent directory path, so write your own in standard POSIX-shell grammar that also works with zsh:

#!/usr/bin/env sh

touchp() {
for arg
do
# Get base directory
baseDir=${arg%/*}

# If whole path is not equal to the baseDire (sole element)
# AND baseDir is not a directory (or does not exist)
if ! { [ "$arg" = "$baseDir" ] || [ -d "$baseDir" ];}; then
# Creates leading directories
mkdir -p "${arg%/*}"
fi

# Touch file in-place without cd into dir
touch "$arg"
done
}

Create directory and files with one command

I recommend -p.

qc() { local p="$1";
if [[ -n "$p" ]];
then mkdir -p "$p" # can be any full or relative path;
else echo "Use: qc <dirpath> [f1[..fN]]"; return 1;
fi;
shift;
for f; do touch "$p/$f"; done;
}

$: qc
Use: qc <dirpath> [f1[..fN]]

$: cd /tmp
$: qc a/b/c 5 4 3 2 1 # relative path
$: qc a/b # no files; dir already exists; no problem
$: qc /tmp/a/b/c/d 3 2 1 # full path that partially exists
$: find a # all ok
a
a/b
a/b/c
a/b/c/1
a/b/c/2
a/b/c/3
a/b/c/4
a/b/c/5
a/b/c/d
a/b/c/d/1
a/b/c/d/2
a/b/c/d/3

How to mkdir only if a directory does not already exist?

Try mkdir -p:

mkdir -p foo

Note that this will also create any intermediate directories that don't exist; for instance,

mkdir -p foo/bar/baz

will create directories foo, foo/bar, and foo/bar/baz if they don't exist.

Some implementation like GNU mkdir include mkdir --parents as a more readable alias, but this is not specified in POSIX/Single Unix Specification and not available on many common platforms like macOS, various BSDs, and various commercial Unixes, so it should be avoided.

If you want an error when parent directories don't exist, and want to create the directory if it doesn't exist, then you can test for the existence of the directory first:

[ -d foo ] || mkdir foo

Create file and directories at the same time

The only thing I can suggest is to mkdir first and then crate file, in fact it's 2 instructions but you can execute it in one line

mkdir test& cd. > test\test.txt

One command to create a directory and file inside it linux command

mkdir B && touch B/myfile.txt

Alternatively, create a function:

mkfile() { mkdir -p -- "$1" && touch -- "$1"/"$2" }

Execute it with 2 arguments: path to create and filename. Saying:

mkfile B/C/D myfile.txt

would create the file myfile.txt in the directory B/C/D.

How can I safely create a nested directory?

On Python ≥ 3.5, use pathlib.Path.mkdir:

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

For older versions of Python, I see two answers with good qualities, each with a small flaw, so I will give my take on it:

Try os.path.exists, and consider os.makedirs for the creation.

import os
if not os.path.exists(directory):
os.makedirs(directory)

As noted in comments and elsewhere, there's a race condition – if the directory is created between the os.path.exists and the os.makedirs calls, the os.makedirs will fail with an OSError. Unfortunately, blanket-catching OSError and continuing is not foolproof, as it will ignore a failure to create the directory due to other factors, such as insufficient permissions, full disk, etc.

One option would be to trap the OSError and examine the embedded error code (see Is there a cross-platform way of getting information from Python’s OSError):

import os, errno

try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise

Alternatively, there could be a second os.path.exists, but suppose another created the directory after the first check, then removed it before the second one – we could still be fooled.

Depending on the application, the danger of concurrent operations may be more or less than the danger posed by other factors such as file permissions. The developer would have to know more about the particular application being developed and its expected environment before choosing an implementation.

Modern versions of Python improve this code quite a bit, both by exposing FileExistsError (in 3.3+)...

try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass

...and by allowing a keyword argument to os.makedirs called exist_ok (in 3.2+).

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.

Bash command to create a new file and its parent directories if necessary

install is your friend:

install -Dv /dev/null some/new/path/base-filename

Is there a way to make mv create the directory to be moved to if it doesn't exist?

How about this one-liner (in bash):

mkdir --parents ./some/path/; mv yourfile.txt $_

Breaking that down:

mkdir --parents ./some/path
# if it doesn't work; try
mkdir -p ./some/path

creates the directory (including all intermediate directories), after which:

mv yourfile.txt $_

moves the file to that directory ($_ expands to the last argument passed to the previous shell command, ie: the newly created directory).

I am not sure how far this will work in other shells, but it might give you some ideas about what to look for.

Here is an example using this technique:

$ > ls
$ > touch yourfile.txt
$ > ls
yourfile.txt
$ > mkdir --parents ./some/path/; mv yourfile.txt $_
$ > ls -F
some/
$ > ls some/path/
yourfile.txt


Related Topics



Leave a reply



Submit