linux - changing order of files
2014-04
I have a series of files named in alphabetical order (xaa.tif to xdg.tif). I need to reverse the order of the filenames so that the last file is processed first in a script. I would like to rename them by adding a number at the beginning of the filename (01xdg.tif to 60xaa.tif).
How can I do that with a bash script on Linux?
Because the file names contain no special characters, including spaces, this can be pretty easily accomplished using ls -r
(that's -r
for --reverse
, not -R
for --recursive
).
/tmp/todo$ ls
/tmp/todo$ touch ab bc bd ef
/tmp/todo$ ls
ab bc bd ef
/tmp/todo$ ls -r
ef bd bc ab
/tmp/todo$
Then you can rename the files using something like:
num=1
for file in $(ls -r)
do
mv $file "$(seq --format='%02g' $num $num)${file}"
num=$(( $num + 1 ))
done
This uses seq
to format the number to use two digits (2
) zero-padded from the left (%0
) with no decimal places (g
) for a total format string of %02g
. There's probably a more efficient way to do it, but with so few files, I wouldn't bother micro-optimizing.
This simply iterates over the list of files (in reverse order), renames each one in turn and increments a counter for each rename.
The final result is:
/tmp/todo$ ls
01ef 02bd 03bc 04ab
/tmp/todo$
Note that the above may very well fall apart if the file names have anything more unusual in them than simple a-z, periods and digits to begin with. Particularly, I'm not sure how well it'll handle spaces.
You can user sort command in Linux
lets say the directory contains following files
# ll /tmp/sort_folder
total 0
-rw-r--r-- 1 root root 0 Dec 18 19:51 a
-rw-r--r-- 1 root root 0 Dec 18 19:51 b
-rw-r--r-- 1 root root 0 Dec 18 19:51 v
The sort command will give you output as below(by default ascending)
# ll /tmp/sort_folder | sort
-rw-r--r-- 1 root root 0 Dec 18 19:51 a
-rw-r--r-- 1 root root 0 Dec 18 19:51 b
-rw-r--r-- 1 root root 0 Dec 18 19:51 v
To reverse sort(descending) you can we -r(reverse) option for sort command
# ll /tmp/sort_folder | sort -r
total 0
-rw-r--r-- 1 root root 0 Dec 18 19:51 v
-rw-r--r-- 1 root root 0 Dec 18 19:51 b
-rw-r--r-- 1 root root 0 Dec 18 19:51 a
This should work:
#!/bin/bash
#
Count=0
ls -r | while read FileName
do
FmtCount=`printf %02d $Count`
mv -i $FileName $FmtCount$FileName
Count=$((Count+1))
done
Here's the explanation:
ls -r
lists the files in reverse orderprintf
formats the count into two zero-padded digits- The backquotes turn the output into a string
I think the rest is self-explanatory, but if not please ask
Lets say I have two folders:
ls /A/
01 - IncorrectName.flac
02 - otherincorrect.flac
ls /B/
01 - CorectName.flac
02 - Othercorrect.flac
How would I move the files from dir A to B, but using the filenames from dir B?
Could I be doing this automatically with $ mv /A/01 - IncorrectName.flac /B/01 - CorrectName.flac
?
The first 5 characters of all filenames are always "NN - "
I am not sure I understand what you want, but this could be it in bash:
#! /bin/bash
for file in "$1"/[0-9][0-9]*.flac ; do
newname="$2"${file#"$1"}
newname=${newname:0:5+${#2}}
mv "$file" "$newname"*
done
Update: should work with command line arguments. The trick was the length of the string was not constant anymore, hence ${#2}
.