0

It has been a long time since I did much bash script writing.

This is a bash script to copy and rename files by deleting all before the first period delimiter:

#!/bin/bash mkdir fullname mv *.audio fullname cd fullname for x in * ; do cp $x ../`echo $x | cut -d "." -f 2-` done cd .. ls 

It works well for file names with no embedded spaces but not for those with spaces.

How can I change the code to fix this simple Linux bash script? Any suggestions for improving the code for other reasons would also be welcome.

Example filenames, some with embedded spaces and some not (from link)

http://www.homenetvideo.com/demo/index.php?/Radio%20%28VLC%29

Ambient.A6.SOMA Space Station.audio Blues.B9.Blues Radio U.K.audio Classical.K3.Radio Stephansdom - Vienna.audio College.CI.KDVS U of California, Davis.audio Country.Q1.K-FROG.audio Easy.G4.WNYU.audio Eclectic.M2.XPN.audio Electronica.E2.Rinse.audio Folk.F1.Radionomy.audio Hiphop.H1.NPR.audio Indie.I4.WAUG.audio Jazz.J6.KCSM.audio Latin.L3.Mega.audio Misc.X7.Gaydio.audio News.N9.KQED.audio Oldies.O1.Lonestar.audio OldTime.Y1.Roswell.audio Progressive.P1.Aural Moon.audio Rock.R8.WXRT.audio Scanner.Z3.Montreal.audio Soul.S1.181.FM.audio Talk.T2.TWiT.audio World.W3.Persian.audio 

http://lh5.googleusercontent.com/-QjLEiAtT4cw/U98_UFcWvvI/AAAAAAAABv8/gyPhbg8s7Bw/w681-h373-no/homenet-radio.png

2
  • 1
    quote the variable with " Commented Aug 4, 2014 at 8:30
  • That was the first thing I tried. I changed both instances of $x to "$x" but got new errors for each file: cp: target `Modern.audio' is not a directory | cp: target `Switzerland.audio' is not a directory |** cp. target `Azur.audio' is not a directory** The corresponding original file names: Blues.B1.SKY Modern.audio Blues.B2.W3 Switzerland.audio Blues.B3.Radionomy Azur.audio Commented Aug 4, 2014 at 9:35

2 Answers 2

2

Whenever you deal with file names that might have spaces in them, you must reference them as "$x" rather than just $x. That's what's causing your cp command to fail.

Your echo command is also problematic. Although echo does the right thing for simple spaces - it echoes a file named A B C as A B C - it will still fail if you have more than one consecutive space in the name, or whitespace that isn't a simple space character.

Instead of passing the file names to external programs for processing, which always requires getting them through the whitespace-hostile command line, you should use bash built-in functions for string manipulations wherever possible, e.g. ${x%%foo}, ${x#bar} and similar functions. The man page describes them under "Parameter expansion".

Sign up to request clarification or add additional context in comments.

Comments

1

Here's my suggestion:

#!/bin/bash shopt -s nullglob mkdir fullname mv *.audio fullname ( cd fullname || exit for x in *; do cp "$x" "../${x#*.}" done ) ls 
  • nullglob prevents * from presenting itself if no file matches it. Just optional.
  • () summons a subshell and saves you from changing back to another directory.
  • || exit terminates the subshell if cd fails to change directory.
  • ${x#*.} removes the <first>. from $x and expands it.

3 Comments

I cut and pasted your code into a new shell document. I kept getting strange vague errors no matter what changes I made. I also noted that the directory created was not fullname. It was fullname\r. I finally decided to use the trusty vi editor to just type your code into a new shell document. Voila, it worked and worked several times. While @KillianFoth pointed in the right direction, yours is a working practical solution. The cd error pipe was a good idea too. I guess I'll have to look into the parameter expansion stuff. Thanks for your help.
@Gooplusplus.com It happens many times when documents are passed from one platform to another. You just happened to save the script in DOS format that's all. DOS formatted text files have lines ending in carriage return (\r) + line feed (\n). To fix that you can just use dos2unix file (never pass more than one file) or sed -i 's|\r||' file.
I used the script as a template for also renaming x.audio to x.radio.asf ----------------------------------------------- cp "$x" "../${x/%.audio/.radio.asf}"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.