Is it possible to change extensions to all files in one folder in Ubuntu? - rename

I want to change extensions from mp3 to mp4 to all files in one directory (folder). Is it possible or I need to write a script to do that?

You could imagine something like this:
for f in *.mp3; do
mv $f ${f/.mp3/.mp4}
done
The part with ${x/a/b} is a string substitution in bash, it replaces a for b in x

Related

(Linux) Recursively overwrite all files in folder with data from another file

I find myself in a situation similar to this question:
Linux: Overwrite all files in folder with specified data?
The answers there work nicely, however, they are for typed-out text. Allow me to provide context.
I have a Linux terminal which the following file structure: (with files & folders irrelevant to the question removed)
root/
empty.svg
svg/
257238.svg
297522.svg
a7yf872.svg
236y27fh.svg
38277.svg
... (~200 other .svg files with arbitrary names)
2903852.svg
The framework I am working with requires those .svg files to exist with those specific filenames, but obviously, it does not care about SVG image they contain. I do not plan on using such files and they take up a hefty amount of space on disk, so I wish to convert them all into empty SVGs, aka the empty.svg file on my root directory, which is a 12x12 transparent SVG file (124 bytes). This way the framework shouldn't error out like it did when I tried simply overwriting the raw data of those SVGs with plaintext using the answer of the question linked at the top of this question. I've tried many methods by trying to be creative with my basic Linux command-line knowledge but no success. How do I accomplish this?
TL;DR: How to recursively overwrite all files in a folder with the raw data of another file from Linux CLI?
Similar to the link, you can use tee command, but instead of echo use cat to copy file contents, where cat is the command to read the contents of the file.
cat empty.svg | tee svg/257238.svg svg/297522.svg <etc>
But if there are a lot of files in svg directory it will be useful to use loop to automate the previous command:
for f in svg/*; do
if [[ "$f" == *.svg ]]; then
cat empty.svg > "$f"
fi
done
Here we use pipes and redirections to connect commands and redirect previous command output.

Zip files within the directory without file extensions

I'm trying to zip all the files within a directory which contains .py files individually. But after zipping the files the output that I'm seeing is .py.zip vs just .zip
Here's the one liner command that I'm trying to execute.
cd scripts/python/
for i in *; do zip $i.zip $i; done
This is what you are looking for:
for i in *py; do
zip "${i%.*}".zip "$i";
done
Explanation
${i%.*}: This makes use of Bash's built in parameter expansion. Here it tries to match everything after %. If it does find a match, it uses everything before the match. https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion for more information.

How to move a certain pattern of subfolders to another folder, keeping the structure using bash?

I have a set of folders like:
/path/to/group1/folder/number123
/path/to/group1/folder/number456
/path/to/group2/folder/number123
/path/to/group2/folder/number456
/path/to/group3/folder/number123
/path/to/group3/folder/number456
And I want to move folders that match /path/to/group*/folder/number123
to the base folder /path/toOther/ so that after the move it looks like:
/path/to/group1/folder/number456
/path/to/group2/folder/number456
/path/to/group3/folder/number456
/path/toOther/group1/folder/number123
/path/toOther/group2/folder/number123
/path/toOther/group3/folder/number123
Is there a way to do this with a move command and wild cards, or will it require more than a 1-liner?
If you don't mind writing a few lines:
cd /path/to
for f in group*/folder/number123
do
d="/path/toOther/${f%/*}"
mkdir -p "$d"
mv "$f" "$d/."
done
Of course you can combine the script into one line. (Or the bash will do this when you recall it with the Up key.)

Move multiple files in same directory without typing directory name each time (Linux)

I have a directory dir with files a, b, c, and I want to move them
mv dir/a dir/b dir/c ...
is the standard way to do it. Is there a shortcut to avoid typing dir/ multiple times? Perhaps like so:
mv dir/(a, b, c) ...
Yes, it's quite similar to what you guessed: mv dir/{a,b,c} dest
Yes, you should be able to do the following
mv dir/{a.out, b.out, c.out} /path/to/newdirectory/
You just need to use curly braces instead of parenthesis.

Linux command line - grabbing parts of the file path

I'm in the process of attempting to convert all my WAV files to FLAC files in such a way that my music directory for FLACs is identical to my music directory for WAVs.
At the moment I have my music archive set up, such that a typical album is here:
/directory1/directory2/directory3/Music/WAV/Artist/Album
So I would like a one-to-one correspondance for my FLAC files that looks as follows:
/directory1/directory2/directory3/Music/FLAC/Artist/Album.
I know that I will have to use find to list all the directories/subdirectories as follows:
find -type d -exec commands.sh
But how do I write the commands.sh file such that it will grab the Artist/Album part of the path in the WAV directory, mkdir the same /Artist/Album in the FLAC directory, and then output the flacs to the FLAC/Artist/Album directory?
I know the command for converting flacs to an output directory of your choice is:
flac -5 --out-prefix="/desired/output/path" *.wav
So I guess I'm just having trouble with grabbing/recreating the file paths!
This would be a whole lot easier in a scripting language like ruby, perl or python. Something like this is a fairly straightforward starter project in any of those languages. There are libraries for find and path manipulation that make this
all pretty easy.
However, there are two posix utilities that can help with splitting apart pathnames. dirname and basename. I think those two and sed should let you do
what you want.
Find will always return relative paths and any exec occurs in the directory of the target by default, if this is not what you want look in the man pages. You can force find to stay in the top level directory.

Resources