shell script tip

When you ever tried to loop over a file listing with filenames containing SPACES, you will get into trouble, because for splits its arguments on those SPACES.

for foo in `ls -1`; do
  echo $foo
done
This will print a list of one word per line.

for foo in `ls -bQ1`; do
  echo $foo
done
This looks promising, because of the -b and -Q switch. -b will escape non-visible characters and -Q quotes the results, but even this attempt will fail with the same problem.

Here is my solution to avoid this problem.

ls -b1 | while read filename; do
  echo "$filename"
done
Passing the ls output to a while loop through a pipe will make it possible to process files with SPACES in its name.

Here is my example to use this and where I've encounterd this problem. I've tried to move some audio files into sub-folders named by the album-tag of the file.

ls -b1 *.flac | while read filename; do
    echo ">>> Processing file: $filename"
    album=""
    flac -t "$filename" 2>/dev/null
    [[ $? -eq 0 ]] && album=$(metaflac --show-tag=album "$filename" | cut -d'=' -f2)
    if [ "$album" != "" ]; then
        album=$(echo $album | strings)
        echo "[ ] Album: $album"
        mkdir -p "$album"
        mv "$filename" "$album"
        echo "<<< $filename moved."
    else
        echo "[!] ERROR on file: $filename"
    fi
done

Update: demod came up with a solution for doing it with a for-loop. (Thanks)

for foo in *; do
  echo "$foo"
done
Which is much easier to read. For aboves usage example we replace

ls -b1 *.flac | while read filename; do
with a much shorter
for filename in *.flac; do

Comments




If you can't read the letters on the image, download this .wav file to get them read to you.
Posted 2009/04/08 23:14 · Julian Knauer
 
blog/2009/04/08.shell.script.tip.txt · Last modified: 2010/02/02 17:04 (external edit)
Recent changes RSS feed Creative Commons License Valid XHTML 1.0 Valid CSS Driven by DokuWiki
[unknown button type]