Find index.html files & Rename with folder name and move file a level up - shell

Little help in solving a workflow with shell script using the find command.
Finding all index.html files in every folder.
We can use this with find command for that.
find ./ -type f -name 'index.html'
Renaming the file index.html with the folder names.
After renaming the files, I wanted to move the files one level up.
I'm stuck at renaming and moving the files one level up.
As I have more than 100k files, Xargs will be handy for this.
Here is code I have so far
find ./ -type f -name 'index.html' | xargs -P 4
Any help in in renaming the index.html files and moving the files one level up?

Instead of xargs you can use find -exec. Inside, you can run a small sh-Script:
find . -mindepth 2 -type f -name 'index.html' -exec sh -c '
d="$(dirname "$1")";
mv "$1" "$d/../$(basename "$d").html";
rmdir "$d";
' find-sh {} \;
Received the help from Askubuntu forum for it :)
Reference : https://askubuntu.com/questions/1236564/find-index-html-files-rename-with-folder-name-and-move-file-a-level-up

Related

copying files from subfolders via grep shell script

I want to write a shell script to do the following :
I have a folder with many subfolders. Each of these subfolders has a *.gz file and some other files which I don't need. I want to move all .gz files into a new subfolder called needed_files (I have already created this subfolder). So I did the following :
I went to the parent folder with all the subfolder and cp /.gz > needed_files/., but this did not work. Can you suggest what I should be doing?
grep is irrelevant here. Use find:
find . ! \( -type d -name needed_files -prune \) -type f -name '*.gz' \
-exec echo mv -t needed_files {} +
POSIX equivalent of that -exec is
-exec sh -c 'echo mv "$#" needed_files' _ {} +
If its output looks good, remove echo.
Btw I noticed that the title says copy but you also say I want to move, so decide on what you exactly want to do and let me know so I can edit my answer.

Mac Terminal command move files from subdirectory to parent

On my Mac I amm trying to move hundreds of files on my NAS drive, from a parent directory with a load of subdirectories (and possibly directories inside them) and put all of the files into one folder.
They don't have the same file extension for all the files.
Is anyone able to help with the terminal command I need to do this? So far I know that find . -type f will list all the files in the directory and subdirectories but Im unsure how to tell it to get them to move them all into another folder.
For anyone else who may have this same issue:
Ive managed to extract just the .jpg's and put them in the parent folder.
find . -type f -iname '*.jpg' -mindepth 2 -print0 | xargs -0 -I{} mv -n '{}' .
Not quite what I wanted - I was hoping to get every single file and put it into a completely different folder if possible but this has got me further than before.
Go inside the source parent directory and use:
find . -type f -exec mv "$PWD"/{} <destination directory> \;
If you want to move all the files to parent directory itself, use it as the destination directory.

How to copy files recursively, rename them but keep the same extension in Bash?

I have a folder with tens of thousands of different file types. Id like to copy them all to a new folder (Copy1) but also rename them all to $RANDOM but keep the extension intact. I realize I can write a line specifying which extension to find and how to name it, but there is got to be a way to do it dynamically, because there are at least 100 file types and may be more in the future.
I have the following so far:
find ./ -name '*.*' -type f -exec bash -c 'cp "$1" "${1/\/123_//_$RANDOM}"' -- {} \;
but that puts the random number after the extension, and also it puts the all in the same folder. I cant figure out how to do the following 2 things:
1 - Keep all paths intact, but in a new root folder (Copy1)
2 - How to have name be $RANDOM.extension, instead of .extension.$RANDOM
PS - by $RANDOM i mean actual randomly generated number. I am interested in keeping folder structure, so we are dealing with a few hundred files at most per directory, but all directories/files need to be renamed to $RANDOM. Another way to look at what I need to do. Copy all contents or Folder1 with all subdirectories and files to Folder2 (where Fodler2 is a $RANDOM name), then rename all folders and files to random names but keep all extensions.
EDIT: Ok i figured out how to rename and keep extension. But I have a problem where its dumping all of the files into the root directory where script is run from. How do I keep them in their respective folders? Command Im using is:
find ./ -name '*.*' -type f -exec bash -c 'mv "$1" $RANDOM.${1##*.}' -- {} \;
Thanks!
Ok i figured out how to rename and keep extension. But I have a
problem where its dumping all of the files into the root directory
where script is run from. How do I keep them in their respective
folders? Command Im using is:
find ./ -name '*.*' -type f -exec bash -c 'mv "$1" $RANDOM.${1##*.}' -- {} \;
Change your command to:
PATH=/bin:/usr/bin find . -name '*.*' -type f -execdir bash -c 'mv "$1" $RANDOM.${1##*.}' -- {} \;
Or alternatively using uuids instead of random numbers:
PATH=/bin:/usr/bin find . -name '*.*' -type f -execdir bash -c 'mv "$1" $(uuidgen).${1##*.}' -- {} \;
Here's what I came up with :
i=1
random="whatever"
find . -name "*.*" -type f | while read f
do
newbase=${f/*./$random$i.} //added counter to filename
cp $f /Path/Name/"$newbase"
((i++))
done
I had to add a counter to random (i), otherwise, if the extensions are similar, your files would overwrite themselves when copied.
In your new folder, your files should look like this :
whatever1.txt
whatever2.txt
etc etc
I hope this is what you were looking for.
Here is the command that worked for me.
find . -name '*.pdf' -type f -exec bash -c 'echo "{}" && cp "$1" ./$RANDOM.${1##*.}' -- {} \;

Unix: Batch move files from multiple subdirectories up 1 level

How can I move files from several subdirectories up 1 level in one terminal command?
File Structure:
path/to/files/A/remove/image.png
path/to/files/B/remove/image.png
path/to/files/C/remove/image.png
path/to/files/D/remove/image.png
path/to/files/E/remove/image.png
Desired Structure:
path/to/files/A/image.png
path/to/files/B/image.png
path/to/files/C/image.png
path/to/files/D/image.png
path/to/files/E/image.png
There are A LOT of directories and each "letter" directory above includes several images. Also, would like to delete the directory the files were moved from.
I had the same requirement (on a mac) but in my case the subdirectory did not have the same name as in the original question making it a bit more complicated. This is what worked for me:
from the "path/to" folder I ran
find . -mindepth 3 -maxdepth 3 -type f | awk -v sq="'" -F "/" '{print "mv -i " sq $0 sq " " sq "./" $2 sq}' > moveup.sh
and then
sh moveup.sh
There are many ways to do it.
This moves all files to their grand-parent directory:
$ find path/to/files -type f -exec mv {} $(dirname $(dirname {})) \;
You add a -name \*.type or whatever, instead of the -type f option, in order to be more specific.
This removes empty directories:
$ find . -type d -empty -exec rmdir {} \;
(although it generates benign errors, which I guess is because the directory structure has been altered while find is still working).
I found the solution to my question...
Using the example directories in my original question, I used this command:
for a in $(find path/to/files -maxdepth 1 -type d); do mv $a/remove/* $a/; rmdir $a/remove; done
"remove" is the name of the subdirectory I wanted to move the files out of within each directory.
The answer was actually found here:
https://serverfault.com/questions/405146/how-to-mass-move-files-one-directory-up

Copy changed files, create a changeset and maintain directory structure

I want to copy just the files i've created/edited today into a separate directory "changeset" whilst maintaining their directory structure
I came up with the following script
cd ./myproject/
find ./* -mtime -1 -daystart -exec cp {} ../changeset/{} \;
The drawbacks of the above is that directories aren't created and the copy throws an error.
I've manually gone into ../changeset/ and create the folder structure until the command runs without errors.. but thats a little tedious.
Is there a simple solution to this?
find * -mtime -1 -daystart -print0 | cpio -pd0 ../changeset
cpio is an old, oddball archival program that is occasionally the best tool for the job. With -p it copies files named on stdin to another directory. With -d it creates directories as needed.
I've found another solution which isn't as elegant as John's but which isn't reliant on cpio, which i dont have.
cd ./myproject/
# Create all directories
find ./* -type d -exec mkdir ../changeset/{} \;
# Copy files
find ./* -mtime -1 -daystart -exec cp {} ../changeset/{} \;
# Delete empty directories, run this several times because after moving a child the parent directory needs to be removed
find ../changeset/ -type d -empty -exec rmdir {} \;

Resources