giobrach giobrach - 1 month ago 14
Bash Question

Bash command ls ordering options

New here (and to coding). I'm writing a simple bash script that helps me change a character into another character in all files of the current directory. Here's the code:

#this script changes characters in all files of the current directory

NUM=$(ls -1 | wc -l | awk '{print $1}')

echo "There are $NUM files in this folder."
echo "Changing $1 to $2 in all their names..."
echo "Done! Here's what happened:"

for i in $(seq 1 $NUM)
OLDNAME=$(ls -1 | head -$i | tail -1)
NEWNAME=$(ls -1 | head -$i | tail -1 | sed -e "s/${1}/${2}/g")

So if I write
./ " " "_"
it should be changing all spaces in the names of all files in the current directory to underscores. Except it doesn't, and I think this is
's fault. The
loop is skipping over some files because
changes the order according to which it sorts the files every time
effectively modifies one of them. So I would need to isolate the names of the files in a way that does not rely on the "last modified" property. I thought of file size, but that won't work if there are two files that have the same size – e.g., I'm trying this code on a directory full of empty files.

Is there a way to sort files with
such that they remain in the same order as
modifies their names?

Answer Source

You can try to substitute your for loop with this one:

find . -type f | while read file
    NEWNAME=`echo $file| sed -e "s/${1}/${2}/g"`
    mv -v "$OLDNAME" "$NEWNAME"

Instead of running ls multiple times in order to get the file to rename, you run find only once and iterate over the results