Reputation: 1
I have a list of files which have number prefixes e.g 1-filename.txt
2-filename.txt
..so on . I found that I skipped a file name as 45-filename.txt
. I have files from 1-filename.txt
to 100-filename.txt
in that directories . Now I want to rearrange all the files with number prefixes without losing their actual name(e.g filename.txt) by creating a bash script but failed to do that. The script I have created as below.
#!/bin/bash
n=1
for i in *.txt;
do
file=$(ls -v "$i" | awk -F- ' { print $NF }')
mv $i "$n-${file}"
let n=n+1
done
But I am not getting required output.
note files have spaces in its name e.g : 1-my first file.txt
2-my second file.txt
....so on.
Upvotes: 0
Views: 808
Reputation: 247210
I would use an array to store the current filename "tail", indexed by the filename prefix number:
files=()
for file in *-*.txt; do
n=${file%%-*} # everthing before the first "-"
name=${file#*-} # everthing after the first "-"
files[n]=$name
done
Iterating over the array indices occurs in numerical order:
c=0
for n in "${!files[@]}"; do
if (( n != ++c )); then
echo mv "${n}-${files[n]}" "${c}-${files[n]}"
fi
done
A demo:
$ touch 1-abc.txt 2-def.txt 3-ghi.txt 8-foo.txt 12-bar.txt 100-baz.txt
$ for file in *-*.txt; do
> n=${file%%-*} # everthing before the first "-"
> name=${file#*-} # everthing after the first "-"
> files[n]=$name
> done
$ declare -p files
declare -a files=([1]="abc.txt" [2]="def.txt" [3]="ghi.txt" [8]="foo.txt" [12]="bar.txt" [100]="baz.txt")
$ c=0
$ for n in "${!files[@]}"; do
> if (( n != ++c )); then
> echo mv "${n}-${files[n]}" "${c}-${files[n]}"
> fi
> done
mv 8-foo.txt 4-foo.txt
mv 12-bar.txt 5-bar.txt
mv 100-baz.txt 6-baz.txt
Remove the echo
if it looks good for you.
Upvotes: 3