Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to rename files named in the form of splitfile[a-z] to splitfile[1-26].csv, that is I want to rename splitfilea to splitfile1.csv and so on.
I tried the following command:

mv splitfile[a-z] splitfile[1-26].csv 

but it doesn't work.Kindly help me, meanwhile I am trying with for loop.

share|improve this question
2  
You may want to consider padding with leading zeros, like splitfile01.csv. The way you suggest, ordinary sorting will put them in the order splitfile1, splitfile10, splitfile11, ... splitfile19, splitfile2, splitfile20, ... which is often inconvenient. In particular, doing cat splitfile*.csv will no longer combine them back into the proper order. – Nate Eldredge Jan 4 at 18:31

With new bash you can use brace expansion of the form {a..z}:

i=1; for f in file{a..z}; do mv "$f.csv" "${f%?}$((i++)).csv"; done
share|improve this answer
    
in file[a-z] is work too but unsorted, so it can be tricked by $(echo file[a-z] | sort) – Costas Jan 4 at 14:21
    
What about using file* instead of file{a..z}? I think it should work... – mohammad .k Jan 4 at 16:32
    
And please note that do mv "$f.csv" should be do mv "$f" according to the question. – mohammad .k Jan 4 at 16:34
    
@mohammad.k It cannot be file* because that would match file_something_not_a_single_letter too. Also it has to be mv "$f.csv" instead of mv "$f", because file{a..z} matches filea, wiithout suffix .csv. – jimmij Jan 4 at 16:40
2  
@Costas - globs are sorted by locale by default. – mikeserv Jan 4 at 17:58

If you have the perl utility rename (sometimes called prename) you can use it to rename your files

rename -n 's/([a-z])$/ord($1)-96/e and $_ .= ".csv"' splitfile?

What this does is to take the last letter of your filenames matching splitfile?, convert the character to its ASCII ordinal equivalent (i.e. a=97, b=98, ...), subtract 96 and replace the matched letter with the result. For all filenames where this substitution was applied successfully the string ".csv" is appended.

The command above won't change your actual files (that's what the -n flag does), it will only print what it would do. Run it once, check the output and, if it is correct, run it again without the -n.

share|improve this answer

With zsh one doesn't need to use a loop, just a zmv function:

autoload -U zmv
i=1 zmv -v '(file)[a-z].csv' '$1$((i++)).csv'

Or if not all the file[a-z].csv may exist:

letters=({a..z})
zmv -v '(file)([a-z]).csv' '$1$letters[(i)$2].csv'
share|improve this answer

This sh script correctly renames files even if files are missing from the a-z sequence:

#!/bin/sh
for n in $(seq 26)
do
    f=$(printf $(printf 'file\%03o.csv' $((n+96))))
    [ -e $f ] && echo mv $f file$n.csv
done
share|improve this answer

This is a way to do it with a POSIX shell, assuming all files exist in the a-z sequence:

#!/bin/sh
i=1
for f in file[a-z].csv
do
    echo mv $f file$i.csv
    i=$((i+1))
done
share|improve this answer
2  
not exactly... consider the cases of matches on a and c but not b. – mikeserv Jan 4 at 14:52
    
@mikeserv, yea, so far only the perl script seems to account for that. – RobertL Jan 4 at 16:42

Another fairly portable solution...

    eval    set "'' $(dc -e'123[1-ddP32P97<a]salax')"  ### reverse-order lowercase ascii
    while   "${2+shift}" 2>&-                          ### only iterate while we should
    do      for f   in ./*["$1"].ext                   ### glob* is fine - sorting's done
            do      [ "${f%%*\]????}" ] &&             ### *null glob* kind of
            echo    mv "$f" "${f%?.*}${?%${10+?}}$#.${f##*.}"  ### echo doesn't mv much
    done;   done                                       ### $? zero-pads to two decimals

After doing the set line above, I then generated a test set for this solution like...

    eval '  for A   in  '"$(printf %1.s%s%1.s "$@" "" ";do for a in$@")"';
            do      echo  "$A$a" > "${A}file$a.ext";        done;   done'

That iteratively skips every two letters for every two letters... if that makes sense. The results were:

ls -m

bfilec.ext, bfilef.ext, bfilei.ext, bfilel.ext, bfileo.ext, bfiler.ext,
bfileu.ext, bfilex.ext, efilec.ext, efilef.ext, efilei.ext, efilel.ext,
efileo.ext, efiler.ext, efileu.ext, efilex.ext, hfilec.ext, hfilef.ext,
hfilei.ext, hfilel.ext, hfileo.ext, hfiler.ext, hfileu.ext, hfilex.ext,
kfilec.ext, kfilef.ext, kfilei.ext, kfilel.ext, kfileo.ext, kfiler.ext,
kfileu.ext, kfilex.ext, nfilec.ext, nfilef.ext, nfilei.ext, nfilel.ext,
nfileo.ext, nfiler.ext, nfileu.ext, nfilex.ext, qfilec.ext, qfilef.ext,
qfilei.ext, qfilel.ext, qfileo.ext, qfiler.ext, qfileu.ext, qfilex.ext,
tfilec.ext, tfilef.ext, tfilei.ext, tfilel.ext, tfileo.ext, tfiler.ext,
tfileu.ext, tfilex.ext, wfilec.ext, wfilef.ext, wfilei.ext, wfilel.ext,
wfileo.ext, wfiler.ext, wfileu.ext, wfilex.ext, zfilec.ext, zfilef.ext,
zfilei.ext, zfilel.ext, zfileo.ext, zfiler.ext, zfileu.ext, zfilex.ext

And then I tested it...

while ...; do ...; done | { HOME=/dev/null; paste -d', ' - ~ - ~; }

mv ./bfilex.ext ./bfile24.ext, mv ./efilex.ext ./efile24.ext,
mv ./hfilex.ext ./hfile24.ext, mv ./kfilex.ext ./kfile24.ext,
mv ./nfilex.ext ./nfile24.ext, mv ./qfilex.ext ./qfile24.ext,
mv ./tfilex.ext ./tfile24.ext, mv ./wfilex.ext ./wfile24.ext,
mv ./zfilex.ext ./zfile24.ext, mv ./bfileu.ext ./bfile21.ext,
mv ./efileu.ext ./efile21.ext, mv ./hfileu.ext ./hfile21.ext,
mv ./kfileu.ext ./kfile21.ext, mv ./nfileu.ext ./nfile21.ext,
mv ./qfileu.ext ./qfile21.ext, mv ./tfileu.ext ./tfile21.ext,
mv ./wfileu.ext ./wfile21.ext, mv ./zfileu.ext ./zfile21.ext,
mv ./bfiler.ext ./bfile18.ext, mv ./efiler.ext ./efile18.ext,
mv ./hfiler.ext ./hfile18.ext, mv ./kfiler.ext ./kfile18.ext,
mv ./nfiler.ext ./nfile18.ext, mv ./qfiler.ext ./qfile18.ext,
mv ./tfiler.ext ./tfile18.ext, mv ./wfiler.ext ./wfile18.ext,
mv ./zfiler.ext ./zfile18.ext, mv ./bfileo.ext ./bfile15.ext,
mv ./efileo.ext ./efile15.ext, mv ./hfileo.ext ./hfile15.ext,
mv ./kfileo.ext ./kfile15.ext, mv ./nfileo.ext ./nfile15.ext,
mv ./qfileo.ext ./qfile15.ext, mv ./tfileo.ext ./tfile15.ext,
mv ./wfileo.ext ./wfile15.ext, mv ./zfileo.ext ./zfile15.ext,
mv ./bfilel.ext ./bfile12.ext, mv ./efilel.ext ./efile12.ext,
mv ./hfilel.ext ./hfile12.ext, mv ./kfilel.ext ./kfile12.ext,
mv ./nfilel.ext ./nfile12.ext, mv ./qfilel.ext ./qfile12.ext,
mv ./tfilel.ext ./tfile12.ext, mv ./wfilel.ext ./wfile12.ext,
mv ./zfilel.ext ./zfile12.ext, mv ./bfilei.ext ./bfile09.ext,
mv ./efilei.ext ./efile09.ext, mv ./hfilei.ext ./hfile09.ext,
mv ./kfilei.ext ./kfile09.ext, mv ./nfilei.ext ./nfile09.ext,
mv ./qfilei.ext ./qfile09.ext, mv ./tfilei.ext ./tfile09.ext,
mv ./wfilei.ext ./wfile09.ext, mv ./zfilei.ext ./zfile09.ext,
mv ./bfilef.ext ./bfile06.ext, mv ./efilef.ext ./efile06.ext,
mv ./hfilef.ext ./hfile06.ext, mv ./kfilef.ext ./kfile06.ext,
mv ./nfilef.ext ./nfile06.ext, mv ./qfilef.ext ./qfile06.ext,
mv ./tfilef.ext ./tfile06.ext, mv ./wfilef.ext ./wfile06.ext,
mv ./zfilef.ext ./zfile06.ext, mv ./bfilec.ext ./bfile03.ext,
mv ./efilec.ext ./efile03.ext, mv ./hfilec.ext ./hfile03.ext,
mv ./kfilec.ext ./kfile03.ext, mv ./nfilec.ext ./nfile03.ext,
mv ./qfilec.ext ./qfile03.ext, mv ./tfilec.ext ./tfile03.ext,
mv ./wfilec.ext ./wfile03.ext, mv ./zfilec.ext ./zfile03.ext,
share|improve this answer

Here's an alternative suggestion, which doesn't support missing files, but I felt the need to try a more "functional" solution that works on tuples:

#!/bin/bash
splitfile_renamer() {
  mv splitfile$1 splitfile$2.csv
}

paste <(echo -en {a..z}"\n") <(seq 26) | while read args
  do splitfile_renamer $args
done

The above uses paste to create the argument tuples (separated by whitespace), and passes them to a pre-made function which then takes them in as numbered arguments.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.