Bash Script That Creates a Directory Structure

Better bash script to create directory structure

Using pure sed:

#!/bin/sed -f

x
G
: loop
s:\([^/]*\)/*\(.*\n\)\([^|]*\)|\s:\2\3\1/:
t loop

s/.*\n//
s:/*$::
h

For this we have to use the hold space (an auxiliary buffer) to store the previous dir path. Then we can remove directories from the hold space and replace them into the respective |s. A more detailed explanation follows:

This script is executed for every line. First thing we do is to exchange ("x") the hold space and the pattern space. Initially, the hold space will be empty, but after the first line the hold space will contain the previous directory path. By exchanging them, we load the previous directory and save the current new directory into hold space.

Next, we append the new directory name to the previous directory path (but both will be separated by newlines). The command used for this is "G".

Now we have to loop for every | character we find. To do this is the tricky part, so bear with me. Suppose we have the following in the current pattern space

Folder/subdir
| | deeper-subdir
  1. Firstly, the \([^/]*\) matches everything before the first slash and captures it (ie. stores it in a "variable", named \1 because it is the first capture group).
  2. Then we skip slashes: /*
  3. Capture everything up to the newline (inclusive) and store into capture \2: \(.*\n\)
  4. Capture everything before the first | character and store into capture \3:
    \([^|]*\)
  5. Skip the | character followed by a space character: |\s

Now, the captures look like this:

  1. Folder
  2. subdir\n
  3. 3.

All we have to do is regenerate the lines reording the captures and adding another slash so they become:

subdir
Folder/| deeper-subdir

After that, we have a conditional branch command "t" that only banches back to the "loop" label if the previous "s" command succeeded. That means that when the string is ready (no more |s), we can exit the loop and continue with the code.

Following the example, the next iteration contains the captures:

  1. subdir
  2. \n
  3. Folder/

After the loop, the first substitute command removes the first line, which contains the path that the new directory hasn't entered, (ie. the new directory is "shallower" than the previous one).

The last substitute command removes any slashes from the end of the line and the last command is a hold command ("h") which copies the current generated path to the hold space, so we can repeat everything for the next line.

Hope this helps =)

How to use the bash script for directory structure?

So this solved my problem:

DIR="$1"
CLIENT="$2"
TMONTH="$(date -j +%d_%B_%Y)"

mkdir -p ${DIR}/${CLIENT}/${CLIENT}_Social_Media/${CLIENT}_${TMONTH}/${CLIENT}_Calendars
mkdir -p ${DIR}/${CLIENT}/${CLIENT}_Social_Media/${CLIENT}_${TMONTH}/${CLIENT}_Design/${CLIENT}_OpenFiles
mkdir -p ${DIR}/${CLIENT}/${CLIENT}_Social_Media/${CLIENT}_${TMONTH}/${CLIENT}_Design/${CLIENT}_Deliverables
mkdir -p ${DIR}/${CLIENT}/${CLIENT}_Campaigns

How to create the folder structure and the file for a given path

Just do the (not soo fancy) but simple:

crfile() {
dir=$(dirname "$1")
mkdir -p "$dir" && touch "$1"
}

while read -r path; do
crfile "$path"
done << EOF
some.txt
./some.txt
../some.txt
.././some.txt
../other/some.txt
/some.txt
/sub/some.txt
/sub/../etc/some.txt
EOF

or if you need shortening

crfile() { mkdir -p "$(dirname "$1")" && touch "$1"; }

from the man mkdir:

-p Create intermediate directories as required. If this option
is not specified, the full path prefix of
each operand must already exist. On the other hand, with this option specified, no error will be
reported if a directory given as an operand already exists
. Intermediate directories are created with
permission bits of rwxrwxrwx (0777) as modified by the current umask, plus write and search permission
for the owner.

Using dirname is much better as trying mangle the path using parameter substitution. read more Bash variable substitution vs dirname and basename

And yes, add the -- if you want - it is good if you expecting files or directories starting with -...

shell script - creating folder structure

Replace

[ ! -d "~/.dir1" ]

by

[ ! -d "${HOME}/.dir1" ]

Bash script to copy the directory structure from source directory into target directory

#!/bin/bash
# 1st argument - source dir, 2nd - destination

function rrr {
for i in `ls $1`
do
if [ -d $1/$i ]
then
mkdir $2/$i
rrr $1/$i $2/$i
fi
done
}

rrr $1 $2

How to create a directory within a directory using shell scripting?

This can be done in a single step, since mkdir -p will create all needed parent directories on the way (that's what the -p option does).

#!/bin/bash
IFS=/
mkdir -p "$*"

Explanation: $* expands to all of the script's arguments, spliced together into a single string, separated by the first character of IFS. That's normally a space character, but here it's set to "/" instead. The double-quotes around it prevent unexpected word-splitting or wildcard expansion.

So, if you run direct.sh dir1 dir2 dir3, it executes mkdir -p "dir1/dir2/dir3", which creates all 3 directory levels (or at least, those that don't already exist).

BTW, in general you should set IFS back to normal after changing it like this. But since there's nothing afterward in the script that might get messed up, and changing it in a script doesn't affect the parent process (the shell you used to run the script), there's no need to set it back in this case.

How to create the directory by using shell script?

If the path is stored in the variable path, then do

mkdir "$path"


Related Topics



Leave a reply



Submit