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}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.