0

I want to rename a couple of file named in an enumerated way. My previous approach was to use this command line:

FILES=`ls "someDir/"`; for f in $FILES; do echo "Processing file: $f"; done;

Echoing the filename is just for demo purposes. The above produces the expected output:

Processing file: File1
Processing file: File2
Processing file: File3
...

However when I run (what I thought is the same thing) the below script, it treats the whole ls output as one file and produces this output:

SCRIPT:
#!/bin/bash
FILES=`ls "someDir/"`

for f in $FILES
do
    echo "Processing file: $f"
done

OUTPUT:
Processing file: File1
File2
File3
...

I can't get my head around it. Also I'm not even sure wether it is ls which is producing this behavior. What is causing this behavior? And why?

muXXmit2X
  • 2,745
  • 3
  • 17
  • 34

1 Answers1

2

See Why you shouldn't parse the output of ls(1), and rather use process-substitution to process command output.

#!/bin/bash

while IFS= read -r -d '' file; do
    echo "$file"
    # Do whatever you want to do with your file here
done < <(find someDir/ -maxdepth 1 -mindepth 1 -type f -print0 | sort -z)

The above simple find lists all files from the required directory (including ones with spaces/special-characters). Here, the output of find command is fed to stdin which is parsed by while-loop.

To ordered sorting of files, add a sort -z piped to the find command output.

Inian
  • 80,270
  • 14
  • 142
  • 161
  • Is there a way to tell `find` to keep the actual order of the files? Since I need them to be processed in the order they are named in. So `File1` first, then `File2` and so on. But `find` produces a miss ordered output like `File325`, `File3`, `File20`, ... . – muXXmit2X Oct 19 '16 at 11:25