How to create a folder recursively in an existing tree of folders (in each existing folder)? - linux

I'm trying to create a new folder in an existing tree with :
find /home/a/Desktop/MyCycles/DavidSilver -type d -exec sh -c '(cd {} && mkdir bin)' ';'
In Ubuntu , but I get an infinite loop of
mkdir: cannot create directory ‘bin’: File exists
Which BTW is not true , since the folder doesn't exist in each of the subfolders of /home/a/Desktop/MyCycles/DavidSilver .
Any idea how can I fix this ?
Thanks

Assuming GNU find(1):
find /home/a/Desktop/MyCycles/DavidSilver -type d -printf '%p/bin\0' | xargs -0 mkdir
Withtout GNU find(1), but assuming directory names don't contain newlines:
find /home/a/Desktop/MyCycles/DavidSilver -type d | \
sed 's!$!/bin!' | \
xargs mkdir

Related

unzip sub directories into one directory

I have one directory with many sub directories 1,2 and more levels deep with zip files.
Could you help me with command to unpack all the zip files in the subdirectories into one directory named /set/ ?
I am on Ubuntu
Use this from the parent directory to extratc all zip file to /set:
find . -name "*.zip" -print | xargs -I{} unzip -o {} -d /path/to/set
If you want no subdirectories in /set, you can use this from /set parent directory:
find . -mindepth 1 -type f -print0 | xargs -I{} mv {} /path/to/set

Recursively go through directories and extract files one directory up CLI

Currently, I am using this
unrar e -r *.rar
To extract files, however this puts everything in my root unraring folder. Current structure
/HomeFolder
/Nextlevel
/RarFolder
rarfile.rar
I want the output to be
/HomeFolder
/Nextlevel
raroutput.ext
How would I do change my command to do this?
Try to use following approach:
find /HomeFolder -type d -name 'RarFolder' -printf '%h\n' | xargs -I{} sh -c 'cd {}; unrar e -r *.rar'
It searches for all nested 'RarFolder' subdirectories in '/HomeFolder', running your unrar command from within subdir containing 'RarFolder' (i.e. '/HomeFolder/Nextlevel' in your example).
To extract files to parent directory of one, containing '*.rar' files, command can be adjusted as:
find /HomeFolder -type f -name '*.rar' -printf '%h\n' | xargs -I{} sh -c 'cd {}/..; unrar e -r *.rar'

how to find and copy files in a sub directory from parent directory linux

I have several parent folders like GJ1, GJ2 etc. Each of these folders contain three images like GJ11_F.jpg, GJ11_P.jpg. I need to only display all the GJ11_F.jpg files including their respective parent directories.
find . -type f -name "*_F.jpg" | xargs cp -t ~/home/ubuntu/
but the above command will only copy the *_F.jpg files and not their respective parent directories GJ1.
Is xargs not the one im supposed to try?
I have also tried -
find . -name "*_F.jpg" -exec sh -c 'rsync -a "${0%/*}" ~/home/ubuntu/' {} \;
One easy way is to use tar which will deal with the directories automatically:
find . -type f -name "*_F.jpg" -print0 | tar c --null -T - | tar xC ~/home/ubuntu/
And here's a solution with a while loop:
find . -type f -name "*_F.jpg" -print0 |
while IFS= read -r -d '' file; do
mkdir -p ~/home/ubuntu/"$(dirname -- "$file")"
cp -ai -- "$file" ~/home/ubuntu/"$file"
done

Linux copying subdirectories with same name to a file

Imagine a directory structure that looks like :
/a1/b1/c1/O
/a1/b2/c2/O
/a1/b3/c3/O
how do I copy all content of the "O" directory to one file?
I've tried cp -r /a1/*/O ~/O and it fails
One more glob pattern needed. Use:
cp -r /a1/*/O/* ~/O
OR to make this command work for any depth use find:
find /a1 -type d -name 'O' -print0 | xargs -0 -I % cp -r %/* ~/O

Copy folder structure (without files) from one location to another

I want to create a clone of the structure of our multi-terabyte file server. I know that cp --parents can move a file and it's parent structure, but is there any way to copy the directory structure intact?
I want to copy to a linux system and our file server is CIFS mounted there.
You could do something like:
find . -type d > dirs.txt
to create the list of directories, then
xargs mkdir -p < dirs.txt
to create the directories on the destination.
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
Here is a simple solution using rsync:
rsync -av -f"+ */" -f"- *" "$source" "$target"
one line
no problems with spaces
preserve permissions
I found this solution there
1 line solution:
find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
I dunno if you are looking for a solution on Linux. If so, you can try this:
$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
This copy the directories and files attributes, but not the files data:
cp -R --attributes-only SOURCE DEST
Then you can delete the files attributes if you are not interested in them:
find DEST -type f -exec rm {} \;
This works:
find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I {} mkdir -p <DEST_DIR>"/{}"
Just replace SOURCE_DIR and DEST_DIR.
The following solution worked well for me in various environments:
sourceDir="some/directory"
targetDir="any/other/directory"
find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
This solves even the problem with whitespaces:
In the original/source dir:
find . -type d -exec echo "'{}'" \; > dirs2.txt
then recreate it in the newly created dir:
mkdir -p <../<SOURCEDIR>/dirs2.txt
Substitute target_dir and source_dir with the appropriate values:
cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p "{}"
Tested on OSX+Ubuntu.
If you can get access from a Windows machine, you can use xcopy with /T and /E to copy just the folder structure (the /E includes empty folders)
http://ss64.com/nt/xcopy.html
[EDIT!]
This one uses rsync to recreate the directory structure but without the files.
http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html
Might actually be better :)
A python script from Sergiy Kolodyazhnyy
posted on Copy only folders not files?:
#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
os.makedirs(os.path.join(sys.argv[1],i))
or from the shell:
python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination
FYI:
Copy top level folder structure without copying files in linux
How do I copy a directory tree but not the files in Linux?
Another approach is use the tree which is pretty handy and navigating directory trees based on its strong options. There are options for directory only, exclude empty directories, exclude names with pattern, include only names with pattern, etc. Check out man tree
Advantage: you can edit or review the list, or if you do a lot of scripting and create a batch of empty directories frequently
Approach: create a list of directories using tree, use that list as an arguments input to mkdir
tree -dfi --noreport > some_dir_file.txt
-dfi lists only directories, prints full path for each name, makes tree not print the indentation lines,
--noreport Omits printing of the file and directory report at the end of the tree listing, just to make the output file not contain any fluff
Then go to the destination where you want the empty directories and execute
xargs mkdir < some_dir_file.txt
find source/ -type f | rsync -a --exclude-from - source/ target/
Copy dir only with associated permission and ownership
Simple way:
for i in `find . -type d`; do mkdir /home/exemplo/$i; done
cd oldlocation
find . -type d -print0 | xargs -0 -I{} mkdir -p newlocation/{}
You can also create top directories only:
cd oldlocation
find . -maxdepth 1 -type d -print0 | xargs -0 -I{} mkdir -p newlocation/{}
Here is a solution in php that:
copies the directories (not recursively, only one level)
preserves permissions
unlike the rsync solution, is fast even with directories containing thousands of files as it does not even go into the folders
has no problems with spaces
should be easy to read and adjust
Create a file like syncDirs.php with this content:
<?php
foreach (new DirectoryIterator($argv[1]) as $f) {
if($f->isDot() || !$f->isDir()) continue;
mkdir($argv[2].'/'.$f->getFilename(), $f->getPerms());
chown($argv[2].'/'.$f->getFilename(), $f->getOwner());
chgrp($argv[2].'/'.$f->getFilename(), $f->getGroup());
}
Run it as user that has enough rights:
sudo php syncDirs.php /var/source /var/destination

Resources