Linux: Find all folders with a particular name, remove them and have a folder copied into the parent directory of those folders - linux

I am trying to see if I can do the following with a single line of command in Linux:
I have a folder called FolderA that sits in 3 different spots in my PC. I have to run a command across a few Linux machines to replace FolderA (they could all be hidden in separate parent folders, get their locations and replace FolderB (which I know where it is and it is a fixed path, say in my current directory, which is different from where FolderA is.) Delete FolderA, and copy FolderB into where FolderA is.
I know this is a lot to do and I can roughly figure out to use find command to get the locations, rm -rf to remove the folders (but I don't know how I can make use of the results in find) and then use cp to copy the folder. However how can I do them in a single line?
Thanks!

Here, I think this should do what you want.
find / -name '*FolderA' -delete -print | xargs -l dirname | xargs -l cp FolderB
The find command will search through your whole filesystem for a path that ends in FolderA, delete it, then print the path of the folder. xargs -l takes each line from the find output and call dirname with each line as the argument. dirname takes a path and truncates the final item on the path. The last command uses xargs to put each line of output from the previous command as the destination of the cp command. Warning: this has not been tested with spaces in the path.

Related

Linux find command explanation

Can someone explain me what does this command do and if I want to try the same thing using git, how should I modify this command?
find . -name CVS -print -exec rm -fr {} \;
This command looks in your current working directory for any directories or files named "CVS" and prints the full path. Then executes a forced recursive removal for each result returned by the find command.
Since there is no filetype present in the name, this command will remove any directory, within your current working directory, named CVS, including all subdirectories and files housed within.

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>/*

How do you move files from one folder to the other?

I am trying to move specific files from one folder to another. Would the below work?
mkdir test
touch test1.sh
touch test2.sh
touch test3.sh
mkdir test2
find test/ | xargs -I% mv % test2
I think this can work:
find ./ -name "test*.sh" | xargs -I% mv % test2
There is somethin odd in your example:
If test1 does not contain any subdirectories, or if you want to move the subdirectories as they are, you could simply do a
mv test1/* test2
(Note that this would (by default) not move entries which start with a period. If this is a problem, you either should consider not using Posix shell but, say, bash or Zsh, or indeed could use find, for the safe side with the -prune option) .
The problem starts with subdirectories. The output of find contains all directories along with the files at the end. The mv inside the xargs would then move, say, a directory test1/foo, and if it later wants to process a file test1/foo/bar/baz.txt, the file is not here anymore. The overall effect would be that you would have moved all the subdirectory (as in my first solution which does not need find), but get in addition plenty of error messages.

Linux find and copy files with same name to destination folder do not overwrite

I want to find and copy all files with *.jpg in one folder includes its sub folder to another folder
I use
find /tempL/6453/ -name "*.jpg" | xargs -I '{}' cp {} /tempL/;
but it overwrite files with same name
for example in /tempL/6453/, there are test (1).jpg test (2).jpg and folder 1, in /tempL/6453/1/, there are also have files with the same name test (1).jpg test (2).jpg
If I use the above command, there are only two files test (1).jpg test (2).jpg in /tempL/, it can not copy all files to /tempL/.
What I want is to copy all files to /tempL/, when there are same file name, just rename them, how to?
What I want is to copy all files to /tempL/, when there are same file name, just rename them, how to?
1) If you only do not what overwrite cp --backup will give you a backup for existing file, with --suffix option of cp, you can also specify the suffix to be used for backup.
2) --parents option of cpwill keep directory tree, i.e. files in folder 1 will be copy to new created 1 folder.
3) If you want to customize your rename processing, you can not use cp command only. write script for it and call it to process the result of find
Install "GNU parallel" and use:
find /tempL/6453/ -name "*.jpg" | parallel 'cp {} ./dest-dir/`stat -c%i {}`_{/}'
{/} ................. gets filename with no full path
I think the same approach should be possible with xargs, but learning about parallel was amazing for me, it gives us many beautiful solutions.
I recommend using echo before cp in order to test your command

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.

Resources