109

I want to mv all the files starting with 'x' to directory 'x'; something like:

mv path1/x*.ext path2/x

and do it for all alphabet letters a, ..., z

How can I write a bash script which makes 'x' loops through the alphabet?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
behzad.nouri
  • 74,723
  • 18
  • 126
  • 124

8 Answers8

175
for x in {a..z}
do
    echo "$x"
    mkdir -p path2/${x}
    mv path1/${x}*.ext path2/${x}
done
Foo Bah
  • 25,660
  • 5
  • 55
  • 79
Kamil Dziedzic
  • 4,721
  • 2
  • 31
  • 47
  • 1
    May I ask why you enclose x with braces on 4th and 5th line? – Jiaqi Li Sep 19 '18 at 21:39
  • It's not required here but well, it works, and makes parameters stand out better;) https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion – Kamil Dziedzic Feb 13 '19 at 18:44
  • 1
    Usually `"$x"` is enough and a better way to make it stand out. – Weijun Zhou Mar 12 '19 at 02:15
  • 1
    @WeijunZhou that is a problem if you want to expand variable x followed by the letters 'y' and 'z'. if you try to expand `"$xyz"` the interpreter will think you're trying to print a variable named xyz while `"${x}yz"` will let the interpreter know exactly what you're trying to do – 4dc0 May 25 '21 at 23:45
  • I meant `"$x"yz`. – Weijun Zhou May 26 '21 at 04:37
48

This should get you started:

for letter in {a..z} ; do
  echo $letter
done
Mat
  • 202,337
  • 40
  • 393
  • 406
28

here's how to generate the Spanish alphabet using nested brace expansion

for l in {{a..n},ñ,{o..z}}; do echo $l ; done | nl
1  a
 ...
14  n
15  ñ
16  o
...
27  z

Or simply

echo -e {{a..n},ñ,{o..z}}"\n" | nl

If you want to generate the obsolete 29 characters Spanish alphabet

echo -e {{a..c},ch,{d..l},ll,{m,n},ñ,{o..z}}"\n" | nl

Similar could be done for French alphabet or German alphabet.

LMC
  • 10,453
  • 2
  • 27
  • 52
  • 1
    Ugly alternative to avoid splitting the alphabet: `for j in $(for i in $(echo {a..z} ñ ch ll ); do echo $i; done| sort | xargs); do echo "Hello-$j"; done` – Enrico Carlesso May 04 '21 at 23:18
5

With uppercase as well

for letter in {{a..z},{A..Z}}; do
  echo $letter
done
Thanh Trung
  • 3,566
  • 3
  • 31
  • 42
4

Using rename:

mkdir -p path2/{a..z}
rename 's|path1/([a-z])(.*)|path2/$1/$1$2' path1/{a..z}*

If you want to strip-off the leading [a-z] character from filename, the updated perlexpr would be:

rename 's|path1/([a-z])(.*)|path2/$1/$2' path1/{a..z}*
anishsane
  • 20,270
  • 5
  • 40
  • 73
4

This question and the answers helped me with my problem, partially.
I needed to loupe over a part of the alphabet in bash.

Although the expansion is strictly textual

I found a solution: and made it even more simple:

START=A
STOP=D
for letter in $(eval echo {$START..$STOP}); do
    echo $letter
done

Which results in:

A
B
C
D

Hope its helpful for someone looking for the same problem i had to solve, and ends up here as well

Alphons
  • 303
  • 2
  • 6
  • depending on which shell you have, this reverse lookup might be useful at times : :::::::::::::::::::::: `printf '%d %d' "'A" "'D"` :::::: `65 68` (note the apostrophe `'` right front of both `A` and `D`) ::::: for some shells, it also works for `Unicode` chars ::::: ::::: ::::: ::: ::::: ::::: ::::: ::::: :: ::::: ::::: ::::: ::::: `printf '%s %d' $'\uACDC' "'"$'\uACDC'` :::::: `곜 44252` – RARE Kpop Manifesto May 25 '23 at 09:20
1

A POSIX compliant version (using AWK):

for letter in $(awk 'BEGIN { for (i=97; i<123; i++) printf("%c ", i) }')
do
    echo $letter
done
hoijui
  • 3,615
  • 2
  • 33
  • 41
-4

Looping through alphabet I hope this can help.

for i in {a..z}

for i in {A..Z}

for i in {{a..z},{A..Z}}

use loop according to need.

Ravikant
  • 11
  • 3
  • 1
    That is already covered in other answers. Please don't add duplicates, or explain how yours is better than the previous answers. – Robert Nov 23 '21 at 14:09