5

Say I want to iterate from letter A to letter Z in csh shell. How do I succinctly do that?

In bash I would do something like

for i in 'A B C ...Z'; do echo $i; done

The point is I don't want to write A through Z, I want something like

[A-Z]

Can you suggest a one line suggestion in AWK or Perl?

vehomzzz
  • 42,832
  • 72
  • 186
  • 216

8 Answers8

7
perl -e 'print for "a" .. "z", "A" .. "Z", 0 .. 9'
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • not what I am looking for. With above , you cannot iterate over each letter and do something with it , say mkdir, as you CANNOT access them individually. – vehomzzz Sep 22 '09 at 20:34
  • 2
    Why can't you iterate over them? The Perl range operator just returns a list. It's a list like any other list. Do whatever you like with it. Furthermore, you need to clarify your question for all the stuff you aren't telling us. – brian d foy Sep 22 '09 at 20:50
  • Because Andrei wants to iterate in the shell. – mob Sep 22 '09 at 22:26
5

Perl

$,=" ";print +(A..Z)

or to use inside a shell:

for i in `perl -e '$,=" ";print +(A..Z)'` ; do echo $i ; done
mob
  • 117,087
  • 18
  • 149
  • 283
4

Hope you have Ruby installed. ;) See this, plain command-line from the shell:

  1. using Ruby to iterate from A to Z and ask to print the letters:

    $ ruby -e ' "a".upto("z") {|letter| print letter}; print "\n"'
    
  2. iterate from A to Z and substitute the value obtained during the current iteration into a string, then print the string:

    $ ruby -e ' "a".upto("z") {|letter| puts "mkdir #{letter}"}'
    
    mkdir a
    mkdir b
    mkdir c
    mkdir d
    ...
    mkdir z
    
  3. use the output of the iteration from A to C as an argument to mkdir, in order to create 3 directories:

    $ mkdir $(ruby -e ' "a".upto("c") {|letter| puts "#{letter}"}')
    

    do a listing to see the results:

    $ ls -al
    drwxr-xr-x  2 iuliu users  4096 2009-10-07 00:09 a
    drwxr-xr-x  2 iuliu users  4096 2009-10-07 00:09 b
    drwxr-xr-x  2 iuliu users  4096 2009-10-07 00:09 c
    

Hope this helps a bit! ;)

regards, Iuliu

Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
Iuliu Pascaru
  • 96
  • 1
  • 4
2

nobody has gawk solution, therefore here's one

awk 'BEGIN{for(i=65;i<=90;i++) printf "%c", i}'
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
1

How about:

for i in $(perl -e 'for my $i ("a".."z") { print "$i "; }'); do ...; done

... or am I misunderstanding what you're trying to accomplish?

(Admittedly the suggestion using $,=" " is even better than the explicit Perl for loop). However, I don't understand value of wrapping the range in +() punctuation. It works for me if I just use: print A..Z; ... though perl -we 'print a..z;' gives me a warning about unquoted strings, but the uppercase version doesn't. The statementprint +(a..z)gives exactly the same warning ... and quoting any of these eliminates the warning. So what's the intent of the+(...)`? Is it just trying to force this into a list context?)

Jim Dennis
  • 17,054
  • 13
  • 68
  • 116
0
foreach i (`jot -c 26 65`)
    echo $i
end
Aoife
  • 1,736
  • 14
  • 12
  • ONE liner please, that's 3 lines. so shell complains with foreach i ( `jot -c 26 65` ); echo $i; end jot: Command not found. foreach? – vehomzzz Sep 22 '09 at 17:16
  • You can simply hit enter after foreach var (...) and the shell will let you continue enter lines until you type end – Zed Sep 22 '09 at 17:19
  • I guess now I understand the question :D – Zed Sep 22 '09 at 17:19
  • jot first appeared in 4.2BSD. It may not be in non-BSD derived OSes. – Aoife Sep 22 '09 at 17:29
0

USING AWK:

You can refer to the ASCII Character Set using the following link:

http://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html

Now to iterate through any set of value, you can use the AWK command as follows:

awk 'BEGIN{ for(i=97;i<123;i++){printf "%c ",i}; printf "\n";}'

Result: a b c d e f g h i j k l m n o p q r s t u v w x y z

Here 97 corresponds to letter "a" and 122 is "z". You can vary the result by using any of the value from the list given above.

  • 65 to 90 for A to Z
  • 48 to 57 for 0 to 9
  • 97 to 122 for a to z

and so on.

Pramod Tiwari
  • 149
  • 1
  • 8
0

I had exactly the same question. The obvious Windows use case is iterating through a list of drive letters. This works in Cygwin:

for i in a b {d..z}; do (du -s "/cygdrive/$i;"); done

Or another example:

for i in a b {d..h} {r..u}; do df /cygdrive/$i | grep -v Filesystem; done

Or yet another example using Perl - thanks to Jim Dennis for his inspiration:

perl -e 'for my $i ("a","b","d".."i","r".."v") { print "$i\n"; }' | sed -e 's/^/\/cygdrive\//'
skeetastax
  • 1,016
  • 8
  • 18