1

this is a three part topic to a two part process that still is not working for me:

Objective: to manipulate a filename then delete it the filename has spaces between the words then the dot .ext

Solution: 1) remove all the white space between the words making on long string of chars with no white space between then then delete that file.

or 2) place quotes on both sides of the filename with spaces then delete that file.

what I did to get my solution. using three different way to reach my solution for the first part of my objective, still not reaching my solution for the second part of my objective.

first how I got my filename out of a directory into a variable.

            find $PWD -name "*.mp3" | while [ $xf  -le $MAXNUM  ] ; 
                       do read FILENAME;

the variable $FILENAME returned the complete path/filename

'/home/userx/ffmpegdir/sub/file with -- lots of spaces and __ ----- _ &&???*# $$ LSD ----in the name _(3).mp3'

I used basename to strip the filename off that string to give me just the filename using just the pref and ext variables.

#strip the old file name off the path from FILENAME

                 c=$FILENAME
                 xpath=${c%/*} 
                 xbase=${c##*/}
                 xfext=${xbase##*.}
                 xpref=${xbase%.*}
                 path=${xpath}
                 pref=${xpref}
                 ext=${xfext}   

then I assign it to another variable.

                #puts quote marks on both sides of the file 
                #with spaces adding the dot (.)
                # extention "mp3" giving me a new file name
                #with the same ext. 

                differentquotes="${pref}.${ext}"

it returns this, the new file with ext. still having spaces and such between the words

  • differentquotes='file with -- lots of spaces and __ ----- _ &&???*# $$ LSD ----in the name _(3).mp3'

when I call rm to remove the file I add quotes around that file name like this

                      rm "\"${differentquotes}\""

that calls to the rm like this with the quotes on both end of the file

  • rm '"file with -- lots of spaces and __ ----- _ &&???*# $$ LSD ----in the name _(3).mp3"'

then all I get is a return error like this

rm: cannot remove `"file with -- lots of spaces and __ ----- _ &&???*# $$ LSD ----in the name _(3).mp3"': No such file or directory

so I decided to try just removing all the spaces between the file name then tried to delete it like this

                        oldname="${pref// }.${ext}"
                        echo "${oldname}" "the hole name now is that "
                        echo
                        echo "calling rm" "${oldname}\"\""
                        rm "${oldname}"

and I got this result, it removed all the spaces between the file name but I still received an error return from rm.

  • oldname='filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3'

  • rm 'filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3' rm: cannot remove `filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3': No such file or directory

so I then tried it like this. I removed all the space within just the pref var first while assigning it to another var name then put the ext on to it then tried to remove it and got this with the same error

                anothernewname="${pref// }"
                echo ${anothernewname}
                putthemtogether="${anothernewname}.${ext}"
                echo ${putthemtogether}
                rm "${putthemtogether}"

I removed all the spaces between the words in just the pref : + anothernewname='filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3)'

then I put the ext back onto the different variable name here:

  • putthemtogether='filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3'

then I called rm to remove it and still got the same error :

  • rm 'filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3'

rm: cannot remove `filewith--lotsofspacesand_-----&&???*#$$LSD----inthename_(3).mp3': No such file or directory + echo

all three times I get the same error- No such file or directory

what is the answer to “what I am doing wrong so that I no longer do it?”

added this: I just tried this: adding the path vatiable to tell it where it is path/filename

                  rm "${path}"/"\"${differentquotes}\""

giving me still an error:

    rm: cannot remove `/home/userx/ffmpegdir/sub/"file  with -- lots of spaces and ____ ----- ___ &&???*# $$ LSD ----in the name _(3).mp3"': No such file or directory

if I put that into the terminal just like that it would work: rm path/"file name with spaces.ext" just as it reads above -- is that not a yes, too?

4
  • Just to be clear: you want to delete file .txt and file with spaces .txt but not file.txt or file with spaces.txt ?
    – evilsoup
    Dec 7, 2013 at 16:59
  • Objective: to manipulate a filename then delete it. the filename has spaces between the words then the dot .ext
    – uxserx-bw
    Dec 7, 2013 at 17:44
  • Objective: to manipulate a filename then delete it. the filename has spaces between the words then the dot .ext what I did to get my solution. using three different way to reach my solution for the first part of my objective, still not reaching my solution for the second part of my objective. it is file with spaces between the words.txt and or too it could be file with spaces between the .txt it is to delete that file no matter where the spaces are at using bash script is the objective
    – uxserx-bw
    Dec 7, 2013 at 18:03
  • as you sill see this removes all the spaces from the file all the way up to the .txt regardless of where the spaces are bbar="${nfoo// /}" again it is the second part of my objective that I am having trouble with
    – uxserx-bw
    Dec 7, 2013 at 18:12

4 Answers 4

1

Always quote your substitutions. Do not add spurious quotes to your strings.

foo="${file#...}"
bar="${file%...}"
baz="$file"
2
  • 1
    Incidentally, assignments with expansion (as you show here) is one place where quotes are optional... Dec 7, 2013 at 18:59
  • While this is good advice, and a lack of quotes around a substitution is probably the cause of the problem (I didn't sift through the meandering, badly formatted, hard-to-follow question to see precisely where the problem is), you've picked one place where the quotes are not necessary. You don't need double quotes in places where the shell expects a single word, such as in an assignment or after case. Dec 8, 2013 at 22:16
1

Your question is extremely long and hard to follow. Here are some mistakes that I caught, there may be others.

do read FILENAME;

This strips whitespace at the beginning and end of the line, and performs backslash expansion (so all backslashes are removed except after another backslash). To process one line literally, use

do IFS= read -r FILENAME

The real problem you're facing is probably this:

rm "\"${differentquotes}\""

You're adding the character " before the file name and the character " after the file name. You're telling rm to delete a file whose name begins and ends with a " character. You probably meant to delete the file whose name is the value of the variable differentquotes (whose name doesn't reflect its value). To delete the file whose name is the value of the variable differentquotes, use

rm -- "$differentquotes"

(The -- is in case the argument begins with -; it isn't necessary with the code you show here since find always prints out names that don't begin with - and if I read your transformation correctly it doesn't risk introducing one.)

The main rule to correctly handle file names with whitespace and other special characters is to always put double quotes around variable and command substitutions. That's "$foo" — the quotes are part of the shell syntax. If you have \" somewhere, that makes the " character part of a string instead of part of shell syntax.

After that you seem to have tried removing spaces and inserting them back. You made the same mistake of adding spurious quote characters inside of what you use as the file name. In addition you can't put back spaces that you've removed — you wouldn't know how many spaces to put back or where.

0

This should do it. Notice the double-quotes around the variables representing the file names with spaces. Be sure to replace .mp3 with whatever extension you want.

#!/bin/bash

LOCATION="/path/to/file"
for FILE in $LOCATION/*; do
  if [[ $FILE == *.mp3 ]]; then
    NEWNAME=`echo $FILE | tr '\ ' _`
    echo "File name was ${FILE}. File name without spaces is $NEWNAME"

    #uncomment this next line to move the file to the new name without spaces
    mv "$FILE" $NEWNAME

    #uncomment this next line if you want to instead remove the file
    #rm "$FILE"

  fi
done
4
  • thank you for taking you time to actually read my code to see what was going on. even thought I figured out a different way to do it with three lines of code within a loop as I added it to the rest of my script killfile="${pref}.${ext}" mv "$killfile" "${killfile//*/killme.k}" rm "killme.k"
    – uxserx-bw
    Dec 7, 2013 at 20:35
  • No problem. If you don't need to rename the file first you could also solve it with find . -maxdepth 1 -type f -name '* *' -delete
    – nyxgeek
    Dec 7, 2013 at 21:04
  • I am using ffmpeg to converting mp3s to 128K giving them a new name with underscores to replace all the spaces and junk between the names in the file, then making directories according to there artist album metadata then putting them into said directories. I just had that problem of getting rid of the old file due to all the spaces and junk between the names of the artist and such. now it is working great and converting, placing new mp3's where they need to be and getting rid of the old file while I just sit here thinking of something else to write in bash script :D thanks!
    – uxserx-bw
    Dec 7, 2013 at 21:28
  • 1
    You can get rid of the if statement if you use for FILE in $LOCATION/*.mp3 Dec 18, 2013 at 18:29
0

Steps I took are in comments below:

  # rename old file regardless of how messes up or not
  # it is using basename to get information needed 
      killfile="${pref}.${ext}"
  # copy old file name to a different file name
  # using the mv command
  # mv ${old file name.ext} ${oldfile name//search pattern/replace with] 
  # gives you a new file with what ever you named it
      mv "$killfile" "${killfile//*/killme.k}" 
  #the then just delete it
             rm "killme.k"

By doing it this way I, found that the system will see it thus it eliminated my file without getting the no such file or directory error - that I was getting.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .