Yes. You can do that w/ tr
in an ASCII locale (which is, for a GNU tr
anyway, kind of its only purview). You can use the POSIX classes, or you can reference the byte values of each character by octal number. You can split their transformations across ranges, as well.
LC_ALL=C tr '[:upper:]\0-\101\133-140\173-\377' '[:lower:][\n*]' <input
The above command would transform all uppercase characters to lowercase, ignore lowercase chars entirely, and transform all other characters to newlines. Of course, then you wind up with a ton of blank lines. The tr
-s
queeze repeats switch could be useful in that case, but if you use it alongside the [:upper:]
to [:lower:]
transformation then you wind up squeezing uppercase characters as well. In that way it still requires a second filter like...
LC... tr ... | tr -s \\n
...or...
LC... tr ... | grep .
...and so it winds up being a lot less convenient than doing...
LC_ALL=C tr -sc '[:alpha:]' \\n <input | tr '[:upper:]' '[:lower:]'
...which squeezes the -c
omplement of alphabetic characters by sequence into a single newline a piece, then does the upper to lower transform on the other side of the pipe.
That isn't to say that ranges of that nature are not useful. Stuff like:
tr '\0-\377' '[1*25][2*25][3*25][4*25][5*25][6*25][7*25][8*25][9*25][0*]' </dev/random
...can be pretty handy as it converts the input bytes to all digits over a spread spectrum of their values. Waste not, want not, you know.
Another way to do the transform could involve dd
.
tr '\0-\377' '[A*64][B*64][C*64][D*64]' </dev/urandom |
dd bs=32 cbs=8 conv=unblock,lcase count=1
dadbbdbd
ddaaddab
ddbadbaa
bdbdcadd
Because dd
can do both unblock
and lcase
conversions at the same time, it might even be possible to pass much of the work off to it. But that can only be really useful if you can accurately predict the number of bytes per word - or at least can pad each word with spaces beforehand to a predictable byte count, because unblock
eats trailing spaces at the end of each block.