Bash : how to rename files that have two extentions? - bash

I call a small program to convert .tap files (retrogaming) into .wav audio files. The program output the new file and just add the .wav extention
example : "file.tap" becomes "file.tap.wav".
I wrote a tiny script to batch the conversion. It works but I cannot manage to rename the file at the end so to remove the ".tap" in the filename.
Note that sometime the original file has lowercase or uppercase.
here is my code. Any help is welcome.
My idea was to 'erase' the ".tap" or ".TAP" in the final filename.
nb : I must use $file.wav like that in the instruction, otherwise it doesn't work.
thank you for your help
#!/bin/bash
for file in `ls`;
do
./tape_converter -11 -a $file $file.wav ;
mv $file ${file/\.tap\.wav/\.wav/};
done

you can modify your script to something like
for f in *.tap; do
<your command> "$f" "${f%.*}.wav"
done
this will name directly the output files with same basename and extension ".wav".

Just remove .tap, then add .wav; there's no need for trying to do a replacement.
for f in *; do
./tape_converter -11 -a "$f" "$f.wav"
mv -- "$f" "${f%.tap}.wav"
done

Here is my final code. Thanks to
thanasisp. It works fine. Happy.
for i in *;
do mv "$i" "$(echo $i|tr A-Z a-z)";
done
mkdir output
for f in *.tap;
do
./tape_converter -11 -a $f ${f%.*}.wav ;
mv *.wav output/
done

Related

remove strange char and adding a prefix when renaming on ssh

i have found this command to replace spaces with underscores:
for file in *.jpg; do mv "$file" ${file// /_}; done
but many pics have chars like ' # ñ and want to remove those automatically and also wanted to add a suffix o prefix.
ex.
pic's#nick_0001.jpg
pic's#nick_0003.jpg
pic's#nick_0003.jpg
to
vacations_pics_nick_0001.jpg
pics_nick_0001_vacations.jpg
can you help me?
for file in *.jpg
do
mv "$file" $(sed 's/[^ [:alnum:]]//g;s/ /_/g;s/^/your_prefix/' <<<"$file")
done
Should do the job
both solution works fine.
is there a way to use that command on a single line, like the example i give to use with others comand together:
for file in * do mv "$file" "${file//[^a-z0-9]/_}" done;
??'
Using bash:
for file in *
do
mv "$file" "${file//[^a-z0-9]/_}"
done
Test:
$ touch "pic's#nick_0001.jpg"
$ ls
pic's#nick_0001.jpg
$ for file in *; do mv "$file" "${file//[^a-z0-9]/_}"; done
$ ls
pic_s_nick_0001_jpg

Renaming file and changing the extension

I have a directory with almost 2000 images and some of them don't have the right extension. And these extensions are formatted like this *.images(xxx) 1. Is it possible to change the extension to jpg
UPDATE
I have this code but it omits the extension.
declare -i i=0;
for f in *;
do
fn=$i".${f##*.jpg}";
mv "$f" "/home/vianney/Desktop/IPIP/$fn";
i=$((i+1));
done
clear
How could I change this code to display the filetype
This can be done with a for loop:
#!/bin/sh
for i in *
do mv "${i}" "${i%.*}.jpg"
done
To expand a bit on the issues addressed in the comments below; here is a variation on the program which appends a sequential numerical suffix to the files as they are processed:
#!/bin/sh
count=0
for i in *.*
do mv "${i}" "${i%.*}.${count}.jpg"
count=$((count + 1))
done
I would go with mv and bash oneliner:
for file in *.images*; do mv "$file" "${file/\.*/\.jpg}"; done;
Let me know if it helped you?

HandBrakeCLI bash script convert all videos in a folder

Firstly, I searched around for my problem. But none can solve it.
I want to convert all videos file in a directory and the output will be saved in another directory. I got a bash script from somewhere I dont remember.
#!/bin/bash
SRC="/home/abc/public_html/filex/store/vids/toriko/VIDEOS HERE"
DEST="/home/abc/public_html/filex/store/vids/toriko/51-100"
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI
PRESET="iPhone & iPod Touch"
for FILE in "`ls $SRC`"
do
filename=$(basename $FILE)
extension=${filename##*.}
filename=${filename%.*}
$HANDBRAKE_CLI -i "$SRC"/$FILE -o "$DEST"/"$filename".$DEST_EXT "$PRESET"
done
the problem is, the output of the file will be without filename.. only ".mp4".
and, there is only 1 file generated.. means, from 50 videos in the folder, only 1 files generated with name ".mp4" and after that, HandBrakeCLI exit.
can anyone fix my code?
I got no experince in bash coding.. so, the right script giiven will be appreciate :)
Your line
for FILE in "`ls $SRC`"
effectively creates only one iteration where FILE contains the list of the files (and it is not able to handle the space in $SRC). Better replace it with
for FILE in "$SRC"/*
Example:
$ ls test
1.txt 2.txt
$ SRC=test; for f in "`ls $SRC`" ; do echo $f; done
1.txt 2.txt
$ SRC=test; for f in "$SRC"/* ; do echo $f; done
test/1.txt
test/2.txt
Side note: you can have a space in there with no problem
$ ls "the test"
1.txt 2.txt
$ SRC="the test"; for f in "$SRC"/* ; do echo $f; done
the test/1.txt
the test/2.txt
I tried this script, and others like it, but I wanted to convert recursive directory tree's and have files placed in the same directory with .mp4 extension and delete .avi files, after much trial and error I gave up on this code and searched for a new code, id like to credit
http://www.surlyjake.com/blog/2010/08/10/script-to-run-handbrake-recursively-through-a-folder-tree/
For the original code!
Here is my modified script, barely modified BTW this script is short, sweet and easy to understand.
#!/bin/bash
# This Script Goes in Root Folder of TV show -- Example Folder Structure
# /Stargate/Season\ 1/Epiosde.avi
# /Stargate/Season\ 2/Epiosde.avi
# /Stargate/handbrake_folder.script
# Outputs all Files back inside same dir's and does all folders inside Startgate DIR
# /Stargate/Season\ 1/Epiosde.mp4
# /Stargate/Season\ 2/Epiosde.mp4
# PRESET = -o flags for CLI can be got from GUI under Activity Log or from https://trac.handbrake.fr/wiki/CLIGuide OR you can use actual Presets!
# PRESET="iPhone & iPod Touch"
PRESET="--modulus 2 -e x264 -q 20 --vfr -a 1 -E ac3 -6 5point1 -R Auto -B 384 -D 0 --gain 0 --audio-fallback ac3 --encoder-preset=veryfast --encoder-level="5.2" --encoder-profile=high --verbose=1"
if [ -z "$1" ] ; then
TRANSCODEDIR="."
else
TRANSCODEDIR="$1"
fi
find "$TRANSCODEDIR"/* -type f -name "*.avi" -exec bash -c 'HandBrakeCLI -i "$1" -o "${1%\.*}".mp4 --preset="$PRESET"' __ {} \; && find . -name '*.avi' -exec rm -r {} \;
BE WARNED: THIS WILL CONVERT THEN DELETE ALL .AVI FILES ABOVE THE SCRIPT IN FILE TREE!
Feel free to remove the
[-name "*.avi"] & [&& find . -name '*.avi' -exec rm -r {} \;]
to disable only converting .avi and removal of .avi or modify to suite another extension.
I have found the solution:
#!/bin/bash
SRC="/home/abc/public_html/filex/store/vids/toriko/VIDEOS HERE"
DEST="/home/abc/public_html/filex/store/vids/toriko/51-100"
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI
for FILE in "$SRC"/*
do
filename=$(basename "$FILE")
extension=${filename##*.}
filename=${filename%.*}
$HANDBRAKE_CLI -i "$FILE" -o "$DEST"/"$filename".$DEST_EXT
done
I just tried using this script with the modification suggested above. I found I need to to put double quotes around the two uses of $FILE in order to handle file names with spaces.
So...
filename=$(basename "$FILE")
and
$HANDBRAKE_CLI -i "$SRC"/"$FILE" -o "$DEST"/"$filename".$DEST_EXT "$PRESET"
I'd rather prefer this solution:
#!/bin/bash
SRC="$1"
DEST="$2"
EXT='mp4'
PRESET='iPhone & iPod Touch'
#for FILE in "`ls $SRC`"; do
for FILE in `find . -type f`; do
FILE=$(basename "$FILE")
filename=$(basename "$FILE")
extension=${filename##*.}
filename=${filename%.*}
HandBrakeCLI -i "$SRC"/$FILE -o "$DEST"/"$filename"."$EXT" "$PRESET"
done

Rename all files in directory from $filename_h to $filename_half?

Dead simple.
How do I rename
05_h.png
06_h.png
to
05_half.png
06_half.png
At least, I think it's simple, but it's hard to Google for this kind of thing unless you already know.
Thanks....
Just use bash, no need to call external commands.
for file in *_h.png
do
mv "$file" "${file/_h.png/_half.png}"
done
Do not add #!/bin/sh
For those that need that one-liner:
for file in *.png; do mv "$file" "${file/_h.png/_half.png}"; done
Try rename command:
rename 's/_h.png/_half.png/' *.png
Update:
example usage:
create some content
$ mkdir /tmp/foo
$ cd /tmp/foo
$ touch one_h.png two_h.png three_h.png
$ ls
one_h.png three_h.png two_h.png
test solution:
$ rename 's/_h.png/_half.png/' *.png
$ ls
one_half.png three_half.png two_half.png
for f in *.png; do
fnew=`echo $f | sed 's/_h.png/_half.png/'`
mv $f $fnew
done
Or in one-liner:
for f in *.png; do mv "$f" "$(echo $f | sed 's/_h.png$/_half.png/g')"; done
Are you looking for a pure bash solution? There are many approaches, but here's one.
for file in *_h.png ; do mv "$file" "${file%%_h.png}_half.png" ; done
This presumes that the only files in the current directory that end in _h.png are the ones you want to rename.
Much more specifically
for file in 0{5..6}_h.png ; do mv "$file" "${file/_h./_half.}" ; done
Presuming those two examples are your only. files.
For the general case, file renaming in has
been covered
before.
Use the rename utility written in perl.
Might be that it is not available by default though...
$ touch 0{5..6}_h.png
$ ls
05_h.png 06_h.png
$ rename 's/h/half/' *.png
$ ls
05_half.png 06_half.png
for i in *_h.png ; do
mv $i `echo "$i"|awk -F'.' '{print $1"alf."$2}'`
done
I had a similar question:
In the manual, it describes rename as
rename [option] expression replacement file
so you can use it in this way
rename _h _half *.png
In the code:
'_h' is the expression that you are looking for.
'_half' is the pattern that you want to replace with.
'*.png' is the range of files that you are looking for your possible target files.
Hope this can help c:
Another approach can be manually using batch rename option
Right click on the file -> File Custom Commands -> Batch Rename
and you can replace h. with half.
This will work for linux based gui using WinSCP etc
One liner:
for file in *.php ; do mv "$file" "_$file" ; done
Although the answer set is complete, I need to add another missing one.
for i in *_h.png;
do name=`echo "$i" | cut -d'_' -f1`
echo "Executing of name $name"
mv "$i" "${name}_half.png"
done
I had to rename the prefix of files and I found this answer with a solution like this:
for i in h_*; do mv ${i/#h_/half_}; done
If pattern begins with #, it must match at the beginning of the
expanded value of parameter. If pattern begins with %, it must match
at the end of the expanded value of parameter.
from man bash
Use the rename utility:
rc#bvm3:/tmp/foo $ touch 05_h.png 06_h.png
rc#bvm3:/tmp/foo $ rename 's/_h/_half/' *
rc#bvm3:/tmp/foo $ ls -l
total 0
-rw-r--r-- 1 rc rc 0 2011-09-17 00:15 05_half.png
-rw-r--r-- 1 rc rc 0 2011-09-17 00:15 06_half.png

Glob renaming in bash

I'm fairly new to bash so sorry if this is kind of a basic question. I was trying to rename a bunch of mp3 files to prepend 1- to their filenames, and mv *.mp3 1-*.mp3 didn't work unfortunately. So I tried to script it, first with echo to test the commands:
for f in *.mp3 ; do echo mv \'$f\' \'1-$f\'; done
Which seems to output the commands that I like, so I removed the echo, changing the command to
for f in *.mp3 ; do mv \'$f\' \'1-$f\'; done
Which failed. Next I tried piping the commands onward like so
for f in *.mp3 ; do echo mv \'$f\' \'1-$f\'; done | /bin/sh
Which worked, but if anyone could enlighten me as to why the middle command doesn't work I would be interested to know. Or if there is an more elegant one-liner that would do what I wanted, I would be interested to see that too.
I think you have to change the command to
for f in *.mp3 ; do mv "$f" "1-$f"; done
Otherwise you would pass something like 'file1.mp3' and '1-file1.mp3' to mv (including the single quotes).
Dry run:
rename -n 's/^/1-/' *.mp3
Remove the -n if it looks correct to run the command. man rename for details.

Resources