Batch removing a sub folder in several parent folders - linux

In linux, I have a group of folders, that all contain the same sub folder structure. E.g.
FolderA/x/y/z/file1.txt
FolderA/x/y/z/file2.txt
FolderB/x/y/z/file1.txt
FolderC/x/y/z/file1.txt
I want to run a batch process to remove one of the subfolders, but leave all files and folders beneath unchanged. E.g. if I were to remove folder "y":
FolderA/x/z/file1.txt
FolderA/x/z/file2.txt
FolderB/x/z/file1.txt
FolderC/x/z/file1.txt
I've tried putting together some combination of find and mv, but can't quite get it right

find . -name y -type d -exec sh -c '
for d; do echo mv "$d"/* "$d"/..; echo rmdir "$d"; done' _ {} +
Remove the echos if the results look like what you expect.

Considering You want to remove one of the subfolders, but leave all files and folders beneath unchanged, here is something you can do. It's NOT an exact Solution, kind of trick that might work for you. I have done it many times on my computer.
You can recursively copy the subfolder's contents to it's parent folder and then traverse to parent directory and then finally recursively remove the subfolder.
Traverse to subfolder
$ cd path/to/SubFolder
Copy all Contents Recursively to Parent Folder
$ cp -R * ..
Traverse to Parent Folder
$ cd ..
Remove recursively Subfolder
$ rm -rf SubFolder/
Say you have a folder y, then,
$ cd path/to/folder/y
$ cp -R * ..
$ cd ..
$ rm -rf y/
For running a Batch Process You can figure out the path to subfolder using find command.
Notice that this trick can consume a lot of time & resources, If you have a lot of folders in the folders. But that works !

Related

Copy or move all files in a directory regardles of folder depth or number

Lets say i have a folder named Pictures and I want to move or copy all files out of this folder.
However I also want to move and harvest all of the files who are in sub folders so:
Pictures/1.png
Pictures/yolo/2.png
Pictures/yolo/swag/sand/3.png
Pictures/extra/fire/4.png
I want to move or copy all these files to another folder like results so I get:
results/1.png
results/2.png
results/3.png
results/4.png
Only I have no idea in advance what sub folders will be in the Pictures folder.
How can I accomplish this in bash/shell scripts ?
I also appreciate making it file type neutral so any files are harvested from their directories (not only .png like in my example) and I have no idea what the file name will be (I only used 1...4 because i did not have any idea how to name them).
You can do it like this:
find /absolute/path/to/Pictures -type f -name '*.png' -exec mv -i {} /absolute/path/to/results \;
Another option is to use xargs
find /absolute/path/to/Pictures -name '*.png' | xargs -I files mv files /absolute/path/to/results
You can simply copy all files and subdirectories along with their contents using cp's recursive option:
cp -pr <source_path>/* <destination_path>/
But, moving them recursively is a bit tricky, you will need to create tar files of the subdirectories and move them and then untar the tar files in destination path. As this is a complex process, as a workaround, you can copy the files/directories recursively and then delete the files from original path.
cp -pr <source_path>/* <destination_path>/ && rm -rf <source_path>/*

delete all folders and files within a linux directory except one folder and all contents inside that folder

I have a directory structure as :-
/usr/testing/member/
---> public--->folder1--->file1
\----> file2
---> folder3:- contains files and folders
---> folder4:- contains files and folders
---> several files
I want to keep the public folder and all its contents (further folders and files within it) but want to delete everything else under the directory /usr/testing/member/. But that also means member folder is not deleted.
Is there any shell script or command that can be used to achieve this exactly as i stated.
Here's one way to do it:
(cd /usr/testing/member; find . -maxdepth 1 \( ! -name . -a ! -name public \) -exec echo rm -fr {} +)
That is: cd into /usr/testing/member, find all files and directories there, without going further below, and exclude the current directory (".") and any file or directory named "public", and execute a command for the found files.
This will print what would be deleted.
Verify it looks good, and then drop the echo.
I think below will do the work,
$ cd /usr/testing/member/
$ rm -rf $(ls | grep -v "public")
explanation:
we are passing everything inside /usr/testing/member/ but public to rm by making use of -v(exclude) option of grep

Wrtie a script to Delete files if it exists in different folder in Linux

I'm trying write a script in linux. Where I have some csv files in Two different folders(A and B) and then after some processing copy of rejected files are moving to Bad Folder.
SO I want bad files to be deleted from Table A and B which have copied to Bad Folder.
Can you help me to write this script for linux?
Best
lets say name of Bad Folder is 'badFolder' and considering 'A', 'B' and 'badFolder' are in same directory
Steps to delete files from folder A and B:
step 1: change current directory to your 'badFolder'
cd badFolder
step 2: delete identical files
find . -type f -exec rm -f ../A/{} \;
find . -type f -exec rm -f ../B/{} \;
The argument -type f tells to look for files, not directories.
The -exec ... \; argument tells that, once it finds a file in 'badFolder', it should run the command rm -f on its counterpart in the A subdirectory.
Because rm is given with the -f option, it will silently ignore files that don't exist.
Also, it will not prompt before deleting files. This is very handy when deleting a large number of files. However, be sure that you really want to delete the files before running this script.
#!/bin/bash
#Set the working folder in which you want to delete the file
Working_folder=/<Folder>/<path>
cd $Working_folder
#command to delete all files present in folders
rm <filenames seperated by space>
echo "files are deleted"
#if you want to delete all files you can use wild card character
# e.g. command rm *.*
# if you want to delete a particular file say for deleting .csv file you can use command rm *.csv command
Set variables containing the paths of your A, B and BAD directories.
Then you can do something along the lines of
for file in ls ${PATH_TO_BAD}
do
rm ${PATH_TO_A}/$file
rm ${PATH_TO_B}/$file
done
This is iterating over the BAD directory and any file it finds, it deletes from the A and B directories.

Using for loop to move files from subdirectories to parent directories

I just made the switch to linux and I am trying to write my first bash script. I have a folder that contains numerous folders, all with subfolders containing files. Something like:
MainFolder
Folder1
Sub1 (Contains many files)
Sub2 (Contains many files)
Folder2
Sub1 (Contains many files)
Sub2 (Contains many files)
.
.
.
I want to move all the files contained in the sub-folders to the their parent folders. My first instinct is to try and write a for-loop. I was able to do one folder at a time with the command:
mv MainFolder/Folder1/*/* MainFolder/Folder1/
But I was hoping to write a bash script to loop over all the folders in the main directory. Here is what I have so far:
#!/bin/bash
dir1="/pathto/MainFolder"
subs= ls $dir1
for i in $subs; do
mv "$dir1/$i/*/*" "$dir1/$i/"
done
This, obviously, does not work, but I do not understand where I am going wrong.
I also tried:
mv MainFolder/*/*/* MainFolder/*/
with pretty disastrous results. Once I get the file move working properly, I would also like to delete the old sub folders within the loop.
Small change. change
subs=ls $dir1
to
subs=`ls $dir1`
Notice the backquotes. Backquotes actually execute the bash command and return the result. If you issue echo $subs after the line, you'll find that it correctly lists folder1, folder2.
Second small change is to remove double quotes in the mv command. Change them to
mv $dir1/$i/*/* $dir1/$i
Double quotes take literal file names while removing quotes takes the recursive directory pattern.
After that, your initial for loop is indeed correct. It will move everything from sub1 and sub2 to folder1 etc.
Yes - this is working solution
#!/bin/bash
mainDir="$(dirname $(realpath $0))/store/media"
subs=`ls $mainDir`
for i in $subs; do
if [[ -d "$mainDir/$i" ]]; then
mv "$mainDir/$i"/* "$mainDir/"
rm -rf "$mainDir/$i"
fi
done
!/bin/bash
dir1="/pathto/MainFolder"
subs=ls $dir1
for i in $subs; do
mv $dir1/$i// $dir1/$i
done

Remove only files and not the directory in linux

I want to know how I can remove all the files in a directory say directory1 contains some 100 files. I just want to remove the files and not the directory.
I know that rmdir directory1 will remove directory1 completely. But I want to only remove all the files inside.
Try this:
rm /path/to/directory1/*
by adding the -r option you can additionally remove contained directories and their content recursively.
find /path/to/directory1 -type f | xargs rm -f
This recursively deletes all normal files in the directory.

Resources