You are herelooping through files with spaces in the filenames in bash

looping through files with spaces in the filenames in bash


By thomas - Posted on 16 May 2006

I sometimes have to transfer files with spaces in the names, I like using a for loop, but the usual way doesn't work. Usual way: for file in `find . -type f|grep .ext$` do /do/something/to $file done To get around this I use a while loop with a read instead. Using the read will read to the end of the line, enclosing within quotes escapes the spaces. Unusual way: find . -type f|grep .ext$ |while read file do /do/something/to "$file" done Or if you don't like using more than one line...and enjoy the unreadable (I'm transferring all my avi files to another computer in this example) find . |grep .avi$ |while read file; do scp "$file" 172.16.1.1:; done
Tags

I was facing the spaces in file name issue and was lookin for a workaround. this sure solved my problem. thanks !!

5+ years later: thanks for sharing!
I was struggling with quotes to solve the problem, and quotes were winning. You saved me quite some time

[...] was soll ich sagen, nach einer stundenlangen Ausprobier-Orgie und Google-Recherchen habe ich hier den passenden Denkanstoß gefunden. #!/bin/bash   find . -name "*.srt" | while read [...]

Thanks, sure helped me.

That was awesome, thank you. You only get an A minus because of your unnecessary use of "grep"...;)

Yet another person helped by this simple tip. Thanks.

What a simple and elegant solution for something that has bugged me for ages.
Life-Saver!

For some reasons, qoute characters are missing in my previous post in the code string..

Well, what do you say. Tried to solve it my self for an hour or so, then found it on google "I'm feeling lucky". Thank you very much.
My problem: Find files in a directory structure, file names can include spaces, create symbolic names in the current directory.
The files are CA root certificates, link names should be the certificate hash. (a Sendmail + TLS configuration issue)

cd /etc/mailcerts/CA
find . -name *pem -print0 | while read -d $'' file
do
ln -s "$file" `openssl x509 -noout -hash < "$file"`.0
done

Thank you! Glad this came up in a google search, was really scratching my head.

You could also use the bash input field separator. Just prepend it to whatever your usual way is. Default is all whitespace.

Example:

IFS="
"

for file in `find . -type f|grep .ext$`
do
/do/something/to $file
done

[...] was soll ich sagen, nach einer stundenlangen Ausprobier-Orgie und Google-Recherchen habe ich hier den passenden Denkanstoß gefunden. #!/bin/bash   find . -name "*.srt" | while read [...]

Awesome -- HUGE thanks!

[...] To loop through files that have spaces in the name, try the following example from narrabilis.com [...]

Thanks. In my case, I had a list of filenames, so:

cat list | while read file
do
doSomething $file
done

I love you. This has bothered me for ages!

I've searched before for a solution like this. It's relatively simple, elegant, and I'm pained that it doesn't seem to be more well known. Thanks.

Interstingly this method still fails with spaces at the end of the file. FYI, however I just did the changes maually since it reduced the number of misses from hundreds to 4. Thanks this is better than the environemtn variable that you can change to get the for loop to work.

I had the wrong path in my previous message.

I have struggled with spaces in pathnames forever using bash.

This is like one of the best tips ever…

Thanks a million !

Solved the BBEdit backup folder problem..

find ~/Documents/BBEdit\ Backups -type f \( -name '*.txt' -o -name '*.applescript' \)|while read file
do
# echo "$file"
mdimport -d 1 /Library/Spotlight/SourceCode.mdimporter "$file"
# mdimport -d 1 /Library/Spotlight/OSAImporter.mdimporter "$file"
done

I have struggled with spaces in pathnames forever using bash. This is like on of the best tips ever...

Thanks a million !

Solved the BBEdit backup folder problem..

find /BACKUP_MAIN/BBEdit_Backups -type f \( -name '*.txt' -o -name '*.applescript' \)|while read file
do
# echo "$file"
mdimport -d 1 /Library/Spotlight/SourceCode.mdimporter "$file"
# mdimport -d 1 /Library/Spotlight/OSAImporter.mdimporter "$file"
done

Thanks for that. Just what the doctor ordered.

Thank you so much!

Many thanks for this. I have been writing shell scripts for 20 years and got stuck. I tried many different ways (xargs etc) and was about to resort to a Tcl script.

This really really helps.. thank you brotha.

Thank you, thank you, thank you. I've been racking my brain trying to get this to work with a "for file in ..." loop with no success. This helps a lot.

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options