LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-16-2013, 05:42 PM   #1
amboxer21
Member
 
Registered: Mar 2012
Location: New Jersey
Distribution: Gentoo
Posts: 291

Rep: Reputation: Disabled
bash script


I had a lot of fun writing this. It's been awhile due to work, dirt bike racing and running 5k's. Work(commercial roofing) is slowing down since the winter is drawing near, tomorrow is the last dirt bike of the season for the north east US. So I am picking programming up once again. Man, it has been awhile!

I downloaded an anime series called Bleach from TPB. They all had mkv extensions and I wanted to convert them all to avi. A boring task if done manually by hand. One by one. So I decided to break open a terminal and write a script for it. Inside the directory, there are 16 files that look like this -> Bleach - 137 -.mkv

I wanted to take the spaces out to prevent problems with the script, replace the hyphens with underscores and then run them through an mkv2avi script I took off the internet for conversions.

Anyway, here is the finished product.

Code:
for i in *.mkv; do mv "$i" $(echo $i | sed 's/\(.[-]\)./\_/g;s/_mkv/.mkv/g'); done; for i in *.mkv; do bash mkv2avi "$i" $(echo "$i" | sed 's/\([0-9]_\)\([0-9]_\)\(.mkv\)/\1\2\.avi/g'); done
I figured I would post it here and see if anyone else wants to give it a try. I don't know about y'all but I enjoy writing scripts any chance I get! I love the challenge and it helps keep my skill up to par. Even sharpens them, depending on the OP's skill set(which mine is rather noobish lol). Again, if anyone wants to try and compact it, refine it, do it better, etc. I would love to see!!

Last edited by amboxer21; 11-18-2013 at 02:04 PM.
 
Old 11-16-2013, 06:40 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Do this once:
Code:
chmod 0755 mkv2avi
...and then:
Code:
# "while" loops are better wrt IFS and all that:
find /some/path -type f -iname \*.mkv | while read ITEM; do
 # kind of like 'tr -s' ';' but then in BASH:
 NEWNAME=(${ITEM}); NEWNAME=${NEWNAME[@]}; mv "${ITEM}" "${NEWNAME// /_}"
 # ...and since the script is executable now you can:
 mkv2avi "${NEWNAME// /_}"
done
Thanks for posting and here are some:

BASH intros:
http://www.gnu.org/software/bash/man...ode/index.html
http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html
http://www.tldp.org/LDP/Bash-Beginne...tml/index.html

BASH scripting guides:
http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
# these are must reads so do read them!

Common questions / problems:
http://mywiki.wooledge.org/ParsingLs
http://mywiki.wooledge.orgDontReadLinesWithFor
http://mywiki.wooledge.org/UsingFind
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes

The Advanced BASH scripting guide:
http://www.tldp.org/LDP/abs/html/

Bourne shell (compatibility):
http://www.grymoire.com/Unix/Sh.html

Also see:
http://www.linuxquestions.org/questi...l-links-35334/
http://www.linuxquestions.org/questi...nd-line-32893/
http://www.linuxquestions.org/questi...ks-4175433508/
 
1 members found this post helpful.
Old 11-16-2013, 07:14 PM   #3
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Code:
# "while" loops are better wrt IFS and all that:
That's only true when you try to read the output of a command with for; a for loop over a glob expression has no problems with IFS or other strange filename characters.

You may want to shopt -s nullglob to get reasonable behaviour in the case where no files match the glob though.
 
1 members found this post helpful.
Old 11-17-2013, 06:38 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I am not sure I follow the original code logic?? Apart from the fact I do not see why there are 2 for loops, surely one was enough, but the seds in both loops would seem to be flawed to me, based on what was written as the original brief?
Quote:
I wanted to take the spaces out to prevent problems with the script, replace the hyphens with underscores and then run them through an mkv2avi script I took off the internet for conversions.
If we use the example given -: Bleach - 137 -.mkv

The first for loop sed -:
Code:
sed 's/\(.[-]\)./\_/g;s/_mkv/.mkv/g'
Firstly, the use of a back reference and escaping the underscore, none of these are required.

Now the output of this looks nice, but it does not meet the brief as we are to remove spaces and replace hyphens with underscores, however, this removes any character, followed by a hyphen, followed by any
other character and replaces the lot with an underscore. Yes you know the format of the original string so using any character instead of a space either side of a hyphen makes a little sense, but,
being that you now have to add an additional sed change to allow for the fact that you turned a period into an underscore (not in the brief), I consider this lazy coding.
So the current output is:
Code:
Bleach_137.mkv
Spaces removed (check), hyphens replaced with underscores (wrong), we started with 2 hyphens and finished with 1 underscore. Again, format wise I understand, but based on the brief, this is wrong.
So based on the known format and the brief, the following would produce what was asked for:
Code:
sed -r 's/[ -]+/_/g'
This would produce:
Code:
Bleach_137_.mkv
Whilst not the 'desired' outcome, it is what was asked for.

The second for loop sed:
Code:
sed 's/\([0-9]_\)\([0-9]_\)\(.mkv\)/\1\2\.avi/g'
We can look at the affect on both the current and the requested output:

1. Current (Bleach_137.mkv) -: changes - - nothing

2. Requested (Bleach_137_.mkv) -: changes - - nothing

Reasons for no changes in either, the sed is looking for a digit followed by an underscore followed by a digit and another underscore. As we can see from both examples, this pattern appears nowhere. Cannot really assist with this one as apart from wanting to change 'mkv' to 'avi' I am not sure what the other change requirement is?

I will say that for sed, if you use -r it saves the need to escape all of your round brackets for back references and that the saving of '.mkv', which is any character followed by 'mkv', is
also not required here.

Lastly, as pointed out by unSpawn, if you wish to improve your bash skills, then sed is not required as parameter substitution can perform the changes you are looking for (caveat: except the last sed as
at this stage we are not aware of its requirement).

Hope some of that helps
 
1 members found this post helpful.
Old 11-18-2013, 02:04 PM   #5
amboxer21
Member
 
Registered: Mar 2012
Location: New Jersey
Distribution: Gentoo
Posts: 291

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post

The second for loop sed:
Code:
sed 's/\([0-9]_\)\([0-9]_\)\(.mkv\)/\1\2\.avi/g'
We can look at the affect on both the current and the requested output:

1. Current (Bleach_137.mkv) -: changes - - nothing

2. Requested (Bleach_137_.mkv) -: changes - - nothing

Reasons for no changes in either, the sed is looking for a digit followed by an underscore followed by a digit and another underscore.
Thats because i was using this to genrate files to test with and forgot to change the sed line to accommodate the actual name.

Code:
for i in {1..10}; do touch "$i"\ \-\ "$i"\ \-\ .mkv; done
Quote:
Originally Posted by grail View Post
Lastly, as pointed out by unSpawn, if you wish to improve your bash skills, then sed is not required as parameter substitution can perform the changes you are looking for (caveat: except the last sed as
at this stage we are not aware of its requirement).

Hope some of that helps
Yes everyone here has said something helpful and I appreciate the feedback. Like ive said i have done any programming since the beginning of the year. I'm just getting back into it now.

Last edited by amboxer21; 11-18-2013 at 02:05 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to end the bash script using commands in bash not manually by pressing ctrl+c Sanpreet Singh Linux - Newbie 1 07-03-2013 01:04 PM
[SOLVED] Converting Script from Linux (GNU) Bash 4 to Solaris Bash 2.05 - Any cheat sheet? oly_r Solaris / OpenSolaris 6 05-03-2013 08:25 AM
[SOLVED] Run multiple bash and php scripts from a bash script charu Programming 5 07-26-2011 02:40 AM
SSH connection from BASH script stops further BASH script commands tardis1 Linux - Newbie 3 12-06-2010 08:56 AM
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:50 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration