change multiple files commandline - linux

I have separated some tracks from mp3 mixes using mp3splt.
BASH: (mp3splt -c('**!!***use .cue file***!!**') [cuefile.cue] [nonstopmix.mp3] ~for anyone interested, is in the Ubu repos~)
And I ended up with these filenames: "Antares" - 01 - "Xibalba".mp3 which is not a format I prefer, now I've made it a little project to change them with a shell script but its more difficult than I anticipated.
I want to change the filename from:
"Antares" - 01 - "Xibalba".mp
to:
01-Antares_-_Xibalba.mp3
so far I've used :
for var in *.mp3; do mv $var {var/"/}; done
and I could repeat that until I'm through, delete the 0x number and add one but I'd like to do it more efficient.
Could anyone give me a pointer (!not a script!) ?
I'd still like to write it myself but there's so much options that I'm a bit lost.
so far I thought to use this program flow:
read all the filenames containing .mp3 and declare as variable $var
strip $var from quotes
select 0x number, append delimiter _ (0x_)
move 0x_ to the beginning of the string
select remaining ' - - ' and change to '-'
done
which bash programs to use? especially changing the 0x puzzles me cuz I need a loop which increments this number and test if it is present in the filename variable and then it has to be changed.

It is easy to do in python 2.x. You can use this logic in any language you want.
import string
a=raw_input('Enter the name of song')
a=a.replace('"', "")
a=a.replace('.mp', ' .mp3')
words = a.split()
print words[2]+'-'+words[0]+'_-_'+words[4]+words[5]
Logic:
I removed ", then make .mp to .mp3, then splitted the string, which created a list ( array ) and then printed the elements according to need.

Try doing this :
rename -n 's/"(\w+)"\s+-\s*(\d+)\s*-\s*"(\w+)"\.mp/$2-$1_-_$3.mp3/' *mp
from the shell prompt. It's very useful, you can put some perl tricks like I does in a substitution.
You can remove the -n (dry-run mode switch) when your tests become valids.
There are other tools with the same name which may or may not be able to do this, so be careful.
If you run the following command (linux)
$ file $(readlink -f $(type -p rename))
and you have a result like
.../rename: Perl script, ASCII text executable
then this seems to be the right tool =)
If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :
$ sudo update-alternatives --set rename /path/to/rename
Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

Related

how to use delimiter in the script to avoid numerical and special characters

Is there any logic to write a shell script to go back up into the previous directory which has "n" number of files like abc-1.0.1-xy.rpm, xyz-3.2.1-bc.rpm, a-bd-2.3.1-ty.rpm etc.. with same pattern.
I need the first name of it before the numeric starts(which can acts as a delimiter) i.e(-(0-9)) can be the delimiter. the output should be abc, xfz, a-bd, etc.
for p in *.rpm; do echo "${p%-*}"; done
I made a try with this command, but it stops and output as xyz-3.2.1. but I need xyz only.
If you need the package name of a rpm, use:
rpm -qp --queryformat '%{NAME}\n' *.rpm 2>/dev/null

Read filename with * shell bash

I'am new in Linux and I want to write a bash script that can read in a file name of a directory that starts with LED + some numbers.(Ex.: LED5.5.002)
In that directory there is only one file that will starts with LED. The problem is that this file will every time be updated, so the next time it will be for example LED6.5.012 and counting.
I searched and tried a little bit and came to this solution:
export fspec=/home/led/LED*
LedV=`basename $fspec`
echo $LedV
If I give in those commands one by one in my terminal it works fine, LedV= LED5.5.002 but if i run it in a bash scripts it gives the result: LedV = LED*
I search after another solution:
a=/home/led/LED*
LedV=$(basename $a)
echo $LedV
but here again the same, if i give it in one by one it's ok but in a script: LedV = LED*.
It's probably something small but because of my lack of knowledge over Linux I cannot find it. So can someone tell what is wrong?
Thanks! Jan
Shell expansions don't happen on scalar assignments, so in
varname=foo*
the expansion of "$varname" will literally be "foo*". It's more confusing when you consider that echo $varname (or in your case basename $varname; either way without the double quotes) will cause the expansion itself to be treated as a glob, so you may well think the variable contains all those filenames.
Array expansions are another story. You might just want
fspec=( /path/LED* )
echo "${fspec[0]##*/}" # A parameter expansion to strip off the dirname
That will work fine for bash. Since POSIX sh doesn't have arrays like this, I like to give an alternative approach:
for fspec in /path/LED*; do
break
done
echo "${fspec##*/}"
pwd
/usr/local/src
ls -1 /usr/local/src/mysql*
/usr/local/src/mysql-cluster-gpl-7.3.4-linux-glibc2.5-x86_64.tar.gz
/usr/local/src/mysql-dump_test_all_dbs.sql
if you only have 1 file, you will only get 1 result
MyFile=`ls -1 /home/led/LED*`

Renaming files like 20141207_190822.jpg to "2014-12-07 19.08.22.jpg" in linux or MacOS X

How in Linux or MacOS X to rename a bunch of files with names 20141207_190822.jpg and 20141207_190823.mp4 to this format:
2014-12-07 19.08.22.jpg
and
2014-12-07 19.08.23.mp4
?
I've found many examples how to just add something to the beginning of filename, but here I need to change the mask by inserting symbols in the middle of filenames and replacing _ with space " ".
Thank you
Try doing this :
$ rename 's#^(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})#$1-$2-$3 $4.$5.$6#' *
There are other tools with the same name which may or may not be able to do this, so be careful.
If you run the following command :
$ file $(readlink -f $(type -p rename))
and you have a result like
.../rename: Perl script, ASCII text executable
then this seems to be the right tool =)
If you don't have this command, search your package manager to install it or do it manually
Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

Using wildcards to exclude files with a certain suffix

I am experimenting with wildcards in bash and tried to list all the files that start with "xyz" but does not end with ".TXT" but getting incorrect results.
Here is the command that I tried:
$ ls -l xyz*[!\.TXT]
It is not listing the files with names "xyz" and "xyzTXT" that I have in my directory. However, it lists "xyz1", "xyz123".
It seems like adding [!\.TXT] after "xyz*" made the shell look for something that start with "xyz" and has at least one character after it.
Any ideas why it is happening and how to correct this command? I know it can be achieved using other commands but I am especially interested in knowing why it is failing and if it can done just using wildcards.
These commands will do what you want
shopt -s extglob
ls -l xyz!(*.TXT)
shopt -u extglob
The reason why your command doesn't work is beacause xyz*[!\.TXT] which is equivalent to xyz*[!\.TX] means xyz followed by any sequence of character (*) and finally a character in set {!,\,.,T,X} so matches 'xyzwhateveryouwant!' 'xyzwhateveryouwant\' 'xyzwhateveryouwant.' 'xyzwhateveryouwantT' 'xyzwhateveryouwantX'
EDIT: where whateveryouwant does not contain any of !\.TX
I don't think this is doable with only wildcards.
Your command isn't working because it means:
Match everything that has xyz followed by whatever you want and it must not end with sequent character: \, .,T and X. The second T doesn't count as far as what you have inside [] is read as a family of character and not as a string as you thought.
You don't either need to 'escape' . as long as it has no special meaning inside a wildcard.
At least, this is my knowledge of wildcards.

Linux rename function not being used correctly

I'm trying to use the rename command in a Terminal in Ubuntu to append a string to the beginning of some avi file names as follows.
rename -n 's/(\w)\.avi$/String_to_add__$1\.avi/' *.avi
So I expect the following:
String_to_add_MyMovie.avi
Problem is that when I run the command it appends the string to the end of the file name, so I end up with the following:
MyMovie_String_to_add_.avi
I'm not sure if I have the perlexpr syntax wrong or something else. Any insight is appreciated.
UPDATE:
Thanks for the suggestions, I tried the suggestions from alno and plundra and made the following modification:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
But now the file gets the string inserted in the middle of the name as follows:
My_String_to_add_Movie
My apologies though, I neglected to mention that the titles are preceded by 3 numeric values, so the file name nomenclature is {3 numbers}-My_Movie.avi so for example 001-My_Movie.avi. But I didn't think this would make a difference since I'm assuming \w+ matches alphanumeric characters, might the '-' be the issue?
Haven't tried Christian's approach yet, I want to be able to use the rename command, or at least understand why it's not working before I try a different approach.
I don't think rename -n is standard. You could do this:
for i in *.avi; do mv $i String_to_add_$i; done
You're only matching a single character with \w, you want \w+, so the complete line would be:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
Correct version:
rename -n 's/(\w+)\.avi$/String_to_add__$1\.avi/' *.avi
You simply forgot + after \w, so it tried to match only one character.

Resources