I used a script to create sub-directories based on the file names of all my mp4 files. My files and newly created sub directories, of the same name, are located in the smae sub directory. Now I need a script to move the mp4 files into each of the files corresponding sub directories. I hope this makes sense. ex: I would like to move "crank (2006).mp4" to the sub directory named "crank (2006)". I have about 1200 of these files to move to their already created sub directories. Please help.
Removing the .mp4 suffix uses %% to delete the sub-string .mp4 from the end of the $f variable.
The mkdir statement ensures that the sub-directory does exist before the mv command.
for f in *.mp4
do
subdir="${f%%.mp4}"
mkdir -p "$subdir"
mv "$f" "$subdir"
done
mmv 'smae/*.mp4' 'smae/#1/#1.mp4'
This is much safer than (noddy) scripts as mmv will check for loops, name collisions, possible problems in the move before moving any file etc.
Following code will,
find the .mp4 files in current directory,
create sub-directories based on the file names of all mp4 files,
move each of the files to corresponding sub directories
for f in *.mp4; do path=$(ls $f | rev | cut -c 5- | rev); mkdir $path; mv $f $path/. ; done
Ex: if "crank (2006).mp4" is available into current directory than new sub directory named "crank (2006)" will be created into current directory and "crank (2006).mp4" file will be moved into that sub-directory.
NOTE: instead of "mv" you can also use "cp" for copy files
Related
Currently I've a lot of .mp4 files with these names:
103160626309temp1ep10.mp4
103160626309temp1ep10.mp4.mp4
148999555452temp1ep6.mp4
148999555452temp1ep6.mp4.mp4
6802547045temp1ep5.mp4
6802547045temp1ep5.mp4.mp4
335587012366temp1ep4.mp4
335587012366temp1ep4.mp4.mp4
...
I must delete all files with single .mp4 and rename .mp4.mp4 to .mp4. Do you have an idea about how can I do it?
I think about using:
for i in ./*.mp4; do
...
and
for i in ./*.mp4.mp4; do
...
But I'm afraid and I can't lose the files or damage them.
Can you help me solve this issue?
Thank you.
You don't need a separate deletion step if you just rename the .mp4.mp4 files over the .mp4 files.
(This assumes that for every .mp4 file there is a corresponding .mp4.mp4 file. If that is not the case, see the "multiple steps" instructions below.)
There are several ways to do that:
Plain shell:
for file in *.mp4.mp4; do
mv -- "$file" "${file%.mp4}"
done
(Use echo instead of mv to see what it's going to do before you run it "for real".)
If you have the perl version of rename (sometimes also known as prename or perl-rename):
rename -f 's/\.mp4\.mp4\z/.mp4/' *.mp4.mp4
(Use rename -n for a dry run.)
If you have the util-linux version of rename:
rename .mp4.mp4 .mp4 *.mp4.mp4
Beware; this will simply replace the first occurrence of .mp4.mp4 in the filenames, but hopefully that'll always be at the end of the filename.
(Again, use rename -n for a dry run.)
If you have mmv:
mmv -d '*.mp4.mp4' '#1.mp4'
If you want to do things in multiple steps:
Create a separate directory for the files you want to keep:
mkdir to-be-kept
Move all .mp4.mp4 files into that directory:
mv *.mp4.mp4 to-be-kept/
Delete all remaining .mp4 files (or move them somewhere else if you want):
rm *.mp4
Or move them somewhere else:
mv *.mp4 some/other/directory
Move the .mp4.mp4 files back:
mv to-be-kept/* .
rmdir to-be-kept
Use one of the above recipes to do the renaming.
You don't need rename -f (use plain rename instead) or mmv -d (use plain mmv instead) because in this case there's no need to overwrite existing files.
I am having difficulty moving files and prepending to the files with Bash.
#!/bin/bash
CAT="WFS_CAT"
for FILENAME in /foo/bar/20*
do
mv "${FILENAME##*/}" "${CAT}.${FILENAME##*/}"
done;
The command errors out. It tries to move the full directory name and prepend to that instead of the individual files.
In this case, it should be much simpler to change the directory to the one your files are located in, as your move command only renames files in this directory. Do you mind trying this?
pushd /foo/bar
for FILENAME in 20*; do
echo mv "${FILENAME}" "${CAT}.${FILENAME}"
done;
popd
I have 50 directories and inside each directory I have a file of the name hist_anh_abs_0. So I have 50 files of the
name hist_anh_abs_0
What I want is the following, I want to run a loop over all 50 directories and which will pull out the file name hist_anh_abs_0 and rename it like hist_anh_abs_0_1, hist_anh_abs_0_2... and finally put all the renamed files in a separate directory.
I did something like this
for file in hist_anh_abs_0
do
mv -i "${file}" "${file/-_abs_0-/-_abs_0_$i-}"
done
But I can't do the part where it will read all the directories and look for the file of name hist_anh_abs_0
ct=0 ;
for f in */hist_anh_abs_0
do
mv $f ${destdir}/${f}_$((ct++));
done
So I have a music folder full of different file formats all mixed together. It IS well-structured: Music/[Artist Name]/[Album Name], with compilation albums in a folder called "Various". Some folders contain just .mp3, .m4a, or .flac files, and some have multiple versions of the album in different file formats. There are also of course various .jpegs of cover art and many of the artist folders contain a .jpeg of the artist's portrait, and there are also many miscellaneous .cue and .log files and other junk.
What I want to end up with is a separate music folder for .flac files, retaining the existing folder structure, removeing them from the existing library. I don't want to end up with empty folders in my current library either, where the album was only in flac. In cases of album folders with multiple formats, I want to move the flacs to the new library along with the cover art, but of course keep the existing cover art in place as well.
I haven't been able to find an application capable of handling this, but I figured a shell script could probably handle it. However I am pathetic with bash and really don't want to break my library.
The files are on a remote disk that I can access with mac, windows, or linux so any approach is good.
Just to fully clarify, here's the logic I'm hoping to code:
Find each subdirectory of /Music that contains .flac files
Copy each of these directories in their entirety (and intermediate parent directories) to a new location in /FLAC, but exclude other audio filetypes (.mp3, .m4a, etc.) from the copy.
If the directory has no other audio filetypes than .flac, delete the entire directory. If it DOES have other audio files, just delete the .flac files.
Do one final sweep through all of /Music to delete any directory that contains no audio files in itself or any subdirectory.
Here's another approach:
find . -type f -name \*.flac -printf "%h\n" |
sort -u |
while read -r dirname; do
new="../flac/$dirname"
echo mkdir -p "$new"
echo mv "$dirname"/*.flac "$new"
jpgs=("$dirname"/*.jpg)
[[ ${#jpgs[#]} -gt 0 ]] && echo cp "$dirname"/*.jpg "$new"
done
find with -printf will print out the directory name of each flac file (relative to the current directory
sort -u to remove the duplicates -- now you have a list of directories containing flac files
the while loop iterates over the directories, clones the directory hierarchy under another directory (amend to suit your needs), moves the flac files, and copies jpg files if there are any.
Remove the echo commands if you're satisfies it works for you.
First make a new parent folder, e.g. "MusicNew" which should be equivalent to the existing 'Music' folder. Then assuming your description of sub-folders and file type that you want to copy, the following lines of code should work.
IFS='\n'
for i in `find Music -mindepth 2 -maxdepth 3 -type f -name "*flac"`;
do
echo ${i};
newfold=`echo ${i} | sed -e 's/Music/MusicNew/g'`;
filename=`basename ${i}`;
fulldirpath="${newfold:0:${#newfold} - ${#filename}}";
echo $fulldirpath/${filename};
mkdir -p ${fulldirpath};
mv ${i} ${fulldirpath}/;
done
Imagine that you have some directories containing both mp3 files and sub-directories, also containing mp3 files, like:
/music/band1/
/music/band2/
/music/band2/dir1/
/music/band2/dir2/
/music/band3/dir1/
/music/band3/dir2/
/music/band4/
...
I would like to create a .m3u file in every directory containing mp3 files - so for example:
/music/band1/band1.m3u
/music/band2/band2.m3u
/music/band2/dir1/dir1.m3u
/music/band2/dir2/dir2.m3u
/music/band3/dir1/dir1.m3u
/music/band3/dir2/dir2.m3u
/music/band4/band4.m3u
The name of .m3u file will be the directory name in which the .m3u is created. (This is just an example directory structure.)
I hope it is clear :)
So far I have this to generate m3u files from *.mp3 files, but only in the actual directory, and name it by directory.
#!/bin/bash\
ls | grep -i mp3 > filelist.txt
mv filelist.txt filelist.m3u
FOLDERNAME=${PWD##*/}
echo $FOLDERNAME
mv filelist.m3u $FOLDERNAME.m3u
What should be added to have it look recursively into every subdirectory of /music, and if there is another sub-sub directory, also look there? Then, execute the m3u-making script in each sub-directory?
Thank you for your help! :)
This should take care of the whole thing for you (no need for the script).
find . -name '*.mp3' -execdir bash -c 'file="{}"; printf "%s\n" "${file##*/}" >> "${PWD##*/}.m3u"' \;