SUMMARY: Mapping of Directory names to lower case
Donald Ballance
donald at control.eng.glasgow.ac.uk
Thu Apr 25 21:45:45 AEST 1991
SUMMARY: Re: Mapping of Directory names to lower case
My original posting was:
> I have a need to be able to get a list of a directory tree and a
> lowercase version of it; this is so that the directory can be
> selected in a case insensitive manner, i.e., they can specify
> contents/info and get information on contents/INFO.
>
> What I would like is a file with:
> lowercase_directory_name Upper_Case_directory_name
> an immaginary example would be:
>
> contents contents
> contents/data contents/Data
> contents/info contents/INFO
> contents/users contents/users
> contents/users/big contents/users/BIG
> contents/users/small contents/users/SMALL
>
> I would like to do this with standard Unix utilities (i.e., awk, sh,
> tr, etc.) if possible. Please mail me directly as I don't have time
> to read this newsgroup. I'll summarize back to the mailing list.
> I'm using a SunOS 4.1.
>
> Thanks in advance
>
> Donald Ballance
First I must appologise as, although I though I'd put the problem
clearly I obviously hadn't. My requirement was to produce the list
I had given as an example.
Many people confimed my impression that the best way to get one
copy of the list was through using find, in particular the command
find . -type d -print
is seems to be the best method of producing the directory list.
The real problem was to create a file with both the lower and upper
versions such that a user could specify the directory, I could run it
through tr A-Z a-z to produce a lower case version, and then use
a shell script like that below to select the correct directory.
for j in $*
do
Dir="$j";
case $j in
contents) Dir="contents
contents/data) Dir="contents/Data
contents/info) Dir="contents/INFO
contents/users) Dir="contents/users
contents/users/big) Dir="contents/users/BIG
contents/users/small) Dir="contents/users/SMALL
.) Dir="unknown";;
esac
.
.
.
done
The commands that I had missed out on were the use of 'pr', 'paste',
and the use of 'sed' to process only the first word. Also the technique
of using awk to translate \012 <CR> to space was interesting.
I haven yet tried out all of the ideas but a number of them definitely
work. Full responses are given below.
Thanks to:
Brian Fitzgerald <fitz at edu.rpi.meche.mml0>
Tony Rems <rembo at com.unisoft>
Jonathan "I." Kamens <jik at edu.MIT.pit-manager>
Luiz Henrique de Figueiredo <LHFIG at EARN.BRLNCC>
John Gordon <gordon at edu.uiuc.cso.osiris>
dkeisen at edu.Stanford.Gang-of-Four (Dave Eisen)
I.Sparry at uk.ac.bath.gdt
jpolcari at com.prime.cat (Joe Polcari x4489)
Jennifer "H." Zemsky <jhz at edu.columbia.cc.cunixa>
andy at com.icom.xwkg (Andrew H. Marrinson)
allbery at org.NCoast (Brandon S. Allbery KB8JRR/AA)
Alan Thew <qq11 at uk.ac.liverpool.uxb>
"Ehud Reshef edr at techunix.technion.ac.il" <edr at IL.AC.TECHNION.CARMEL>
Perry Statham <perry%statham at edu.utexas.cs>
Jean-Marc_de_chez_Hackers_alias_ <edgard at fr.gipsi.cao>
Braham Levy <pha21 at uk.ac.keele.seq1>
pfinkel at com.att.oac (Paul D Finkel)
-----------------------------------------------------------------------------
From: Brian Fitzgerald <fitz at edu.rpi.meche.mml0>
If you just want to list a lower case version of anything, pipe it
through tr with the appropriate arguments. If really want to store
this duplicate information in a file somewhere, then you can use tr and
awk to accomplish that, but before long the file will be out of date.
However, if, as you say, you want to be able to "select" something in a
case insensitive manner then echo the thing, pipe it through tr,
enclose it in back quotes, and use the rresult as part of a command.
For example, in a c shell, to cd to a directory in a case insensitive manner
try this alias.
[12] mml0 % alias cd 'cd `echo \!:1 | tr "[A-Z" "[a-z]"`'
[13] mml0 % cd BIN
[14] mml0 % pwd
/home/staff/fitz/bin
Use the backquoting scheme in a shell script somehow to accomplish
what you are really trying to do.
This works for Sun OS, but /usr/5bin/echo and /usr/5bin/tr behaves
differently from /bin/echo and/bin/tr
Brian
-----------------------------------------------------------------------------
From: Tony Rems <rembo at com.unisoft>
If you're just going to put the names into a file,
then use grep -i. This does case insensitive pattern matching.
Or if you really must have it this way, then do a
find . -print | tr '[A-Z]' '[a-z]'
-Tony
-----------------------------------------------------------------------------
From: Jonathan "I." Kamens <jik at edu.MIT.pit-manager>
Personally, I would do this with perl, because I *know* that perl has all of
the necessary features, including the ability to do what "find" does and the
ability to convert upper-case to lowercase.
You could also do it with awk, if you could figure out in awk how to convert
upper-case to lowercase, and this is, indeed, possible, if you have a version
of awk that does functions. This has been discussed on the net in the past.
However, if you don't want to use perl and don't want to figure out how to
do tr conversions in awk (or don't have an awk that supports functions), you
can do something like this:
#!/bin/sh
find "$1" -type d -print | while read dir ; do
echo `echo "$dir" | tr '[A-Z]' [a-z]'` "$dir"
done
Now, for efficienty, I would replace echo with /bin/echo and tr with /bin/tr
unless your shell has either of these builtin (the former is possible, the
latter unlikely).
This doesn't put the directory names in even columns; if that's necessary,
you can pipe the output of the loop through awk to do that, like this:
#!/bin/sh
find "$1" -type d -print | while read dir ; do
echo `echo "$dir" | tr '[A-Z]' [a-z]'` "$dir"
done | awk '{printf("%-30s %-30s\n", $1, $2)}'
--
Jonathan Kamens USnail:
MIT Project Athena 11 Ashford Terrace
jik at Athena.MIT.EDU Allston, MA 02134
Office: 617-253-8085 Home: 617-782-0710
-----------------------------------------------------------------------------
From: Luiz Henrique de Figueiredo <LHFIG at EARN.BRLNCC>
Assuming you already have the filename list called l, try:
tr A-Z a-z <l | paste - l
A list can be obtained using find.
----------------------------------------------------------------------
Luiz Henrique de Figueiredo lhfig at brlncc.bitnet
IMPA/CNPq lhfu at lncc.bitnet
Estrada Dona Castorina 110
22460 Rio de Janeiro, RJ, Brasil (021) 294-9032 r226
----------------------------------------------------------------------
-----------------------------------------------------------------------------
From: John Gordon <gordon at edu.uiuc.cso.osiris>
You could probably do a lot of this with a `ls -RC | grep "\/"' (to
recursively print all files and strip out directories) and "tr". (to
translate upper to lower. do a "man tr" to learn more.)
---
John Gordon
Internet: gordon at osiris.cso.uiuc.edu #include <disclaimer.h>
gordon at cerl.cecer.army.mil #include <clever_saying.h>
-----------------------------------------------------------------------------
From: dkeisen at edu.Stanford.Gang-of-Four (Dave Eisen)
To: donald
This isn't pretty (it forks a new process for every file in the directory
tree), but it's a start:
:
# Shell program to output a list of files on a system in the form
# lowercase_filename actual_filename
find / -print |
while read file
do
echo $file | tr "[A-Z\012]" "[a-z ]"
echo $file
done
where the tr command takes upper case letters and makes them lower case
and converts newlines to tabs.
I hope you can do better than this.
--
Dave Eisen
1101 San Antonio Rd. Suite 102
Mountain View, CA 94043
(415) 967-5644 dkeisen at Gang-of-Four.Stanford.EDU (for now)
-----------------------------------------------------------------------------
From: I.Sparry at uk.ac.bath.gdt
Sorry, your question is not quite clear to me. Do you want to
be able to generate the file, or to use it?
To generate it, you can do
find * -print > /tmp/dir_list
/usr/ucb/ex - <<! /tmp/dir_list
%s/.*/& \L&/
%s/\(.*\) \(.*\)/\2 \1/
w
q
!
To use it, use any of the pattern searchers (e.g. grep) followed by
either 'cut' (if you have the system 5 stuff loaded), or "awk '{print $2}'".
Feel free to explain to me why I am stupid not to understand exactly what
you want to do, or to ask for more information/help.
Icarus
-----------------------------------------------------------------------------
From: jpolcari at com.prime.cat (Joe Polcari x4489)
Try this:
alias LS 'ls|tee /usr/tmp/$$;echo "----------";cat /usr/tmp/$$|tr A-Z a-z'
Then type LS
-joe
-----------------------------------------------------------------------------
From: Jennifer "H." Zemsky <jhz at edu.columbia.cc.cunixa>
>I have a need to be able to get a list of a directory tree and a
>lowercase version of it; this is so that the directory can be
>selected in a case insensitive manner, i.e., they can specify
>contents/info and get information on contents/INFO.
>
this may not be possible, imho.
many unix systems are case-sensitive; thus, given any subdir name with N
letters, you can have 2^N subdirs:
~/abc ~/ABc
~/Abc ~/aBC
~/aBc ~/aBC
~/abC ~/ABC
of course, my knowledge has limitations. but, i think you will not be
able to do this without a major test to check any combination
of upper- and lower-case letters.
>
>Thanks in advance
personally, i think AtDhVaAnNkCsE looks better. :^)
--jhz
-----------------------------------------------------------------------------
From: andy at com.icom.xwkg (Andrew H. Marrinson)
Donald,
If you haven't been inundated with responses already, your problem
caught my fancy. Here is a short shell script to do what you want.
One warning: I don't run SunOS. Either your tr or your pr might be
different, so beware.
------------ BEGIN SHELL SCRIPT -------------------
#! /bin/sh
cat > /tmp/map$$
tr '[A-Z]' '[a-z]' < /tmp/map$$ | pr -m -s' ' -t /tmp/map$$ -
rm -f /tmp/map$$
------------ END SHELL SCRIPT ---------------------
I wish I could find a way to avoid the temporary file, but Unix pipes
aren't that flexible! Also, the quotes after pr's -s surroud a single
tab. It may not make it through all the mailers in the world. (You
may want to use a different separator -- just change this character.)
Hope this helps...
--
Andrew H. Marrinson
Icom Systems, Inc.
Wheeling, IL, USA
(andy at icom.icom.com)
-----------------------------------------------------------------------------
From: allbery at org.NCoast (Brandon S. Allbery KB8JRR/AA)
In your article <4806 at gumby.Altos.COM> ["Mapping of Directory names to lower case"], you wrote:
+---------------
| lowercase version of it; this is so that the directory can be
+-^ that was the first line of your message. the line-eater lives! :-)
+---------------
| contents contents
| contents/data contents/Data
| contents/info contents/INFO
| contents/users contents/users
| contents/users/big contents/users/BIG
| contents/users/small contents/users/SMALL
+---------------
cd /your/database
find . -print |
sed -e 's!^\./!!' \
-e h \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmopqrstuvwxyz/ \
-e 's/$/ /' \
-e G > DIRECTORY
Amaze your friends with the power of ordinary UNIX commands! :-)
++Brandon
--
Me: Brandon S. Allbery Ham: KB8JRR/AA on 2m, 220, 440, 1200
Internet: allbery at NCoast.ORG (QRT on HF until local problems fixed)
America OnLine: KB8JRR // Delphi: ALLBERY AMPR: kb8jrr.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery KB8JRR @ WA8BXN.OH
-----------------------------------------------------------------------------
From: Alan Thew <qq11 at uk.ac.liverpool.uxb>
grep has a -i option which ignores case.
-----------------------------------------------------------------------------
From: "Ehud Reshef edr at techunix.technion.ac.il" <edr at IL.AC.TECHNION.CARMEL>
why not use tr ?
just have your file use all lowercase, and do:
directory=`echo $* | tr '[A-Z]' '[a-z]'`
- --
===============================================================================
=
_ | Ehud Reshef | No good deed
/_ /_ _ / | EDR @ Techunix .Bitnet | goes
(___ / ) (_( (_/ | EDR @ Techunix .Technion.Ac.IL | unpunished.
-----------------------------------------------------------------------------
From: Perry Statham <perry%statham at edu.utexas.cs>
As I see it you can do it several ways.
If you have a file like:
contents contents
contents/data contents/Data
contents/info contents/INFO
you could do it by writing a shell bourne function like this:
xcd() {
cd `grep -y "^$1" /tmp/dirfile | awk '{ print $2 }'`
}
or you could simply ignore case by using a program/script to change
$ xcd contents/info
to perform
$ cd [cC][oO][nN][tT][eE][nN][tT][sS][/][iI][nN][fF][oO]
Here is a short C program that will change it's first parameter into the
correct format:
/*
* This program prints out its string argument as a
* regular expression that ignores case.
*/
#include "stdio.h"
#include "ctype.h"
main(argc,argv)
int argc; char *argv[];
{
int pntr;
for(pntr=0; argv[1][pntr]; pntr++) {
if (isalpha(argv[1][pntr])) {
putc('[',stdout);
putc(toupper(argv[1][pntr]),stdout);
putc(tolower(argv[1][pntr]),stdout);
putc(']',stdout);
} else {
putc(argv[1][pntr],stdout);
}
}
putc('\n',stdout);
}
With this program you would not have to worry about keeping your data
file updated.
Perry Lee Statham \ / perry at statham.cactus.org
- * - h> (512) 335-3881
Can You Grok It? / \ w> (512) 467-1396
-----------------------------------------------------------------------------
From: Jean-Marc_de_chez_Hackers_alias_ <edgard at fr.gipsi.cao>
Hi Donald,
Here is a sh/ksh program wich can, i think, do what you need:
------------------------- cut here -------------------------
#@(#) Just for fun, try it :-) Jean_Marc (edgard at cao.gipsi.fr) [91/04]
read INPUT
DIR=`dirname $INPUT`
case $1 in -A) OUT=`basename $INPUT | tr '[a-z]' '[A-Z]'`;;
*) FILE=`basename $INPUT`
OUT=`echo $FILE | cut -c1 | tr '[a-z]' '[A-Z]'`
OUT=$OUT`echo $FILE | cut -c2-`
esac
echo "$DIR/$OUT"
------------------------- cut here -------------------------
With "/toto/tutu/titi" in stdin,
* if you run it without argument, you get:
/toto/tutu/titi
* if you run it with '-A' argument, you get:
/toto/tutu/TITI
Hope that helps,
/* edgard at cao.gipsi.fr Voice: (33) (1) 30 60 75 47 */
/* <- In stereo where available -> Fax: (33) (1) 30 60 75 90 */
-----------------------------------------------------------------------------
From: Braham Levy <pha21 at uk.ac.keele.seq1>
Donald,
here's a method that might suit your needs. it consists of an
awkscrpit and a shell script. an awkscript follows :-
<=====Cut It Here=====>
BEGIN { FS = "/" }
{ printf "%s ", "lastupper" }
{ if ( NF > 1 ) {
for (i = 1; i < NF; i++) { printf "%s/", $i }
print " " $NF;
}
else { print $NF }
}
END {}
<====End it Here===>
what it does ... splits each line into tokens by setting the field
separator (FS). echoes these tokens out concatting a slash unless its
the last token in which case it echoes it prepending a space.
and a shell script
<====Cut It Here====>
#!/bin/sh
# lastupper concatenates two strings making last on UPPER case
#
# j braham levy april 1991 (all wrongs reserved)
#
echo -n $1
echo $2 | tr a-z A-Z
<===End it Here=====>
what it does... take two arguments, concatting the UPPER case of the 2nd
to the first.
i did it this way 'cause i couldn't figure out how to do a lower to
upper conversion in awk !!
call the awkscript awkscript (for want of anything better) and the shell
script lastupper and then
awk -f awkscript < filelist | sh
will do the job... an example for you
consider the input file
<====Cut It Here====>
contents
contents/data
contents/info
contents/users
contents/users/big
contents/users/small
<====End it Here====>
will produce the following output (well it did on the sequent)
<===Cut It Here====>
contents
contents/DATA
contents/INFO
contents/USERS
contents/users/BIG
contents/users/SMALL
<===End it Here===>
Voila !
i know its crude but as they say "Don't knock it, it's free" (apologies
to D.Adams).
happy hacking
braham
email: brahamlevy at uk.ac.keele (or similar)
mail-mail : phone +44-782-621111x3943
j braham levy
UDSP Lab,
Electrical Engineering Group,
Dept. of Physics,
University of Keele,
Keele, Staffs,
UK.
-----------------------------------------------------------------------------
From: pfinkel at com.att.oac (Paul D Finkel)
LIke this?
echo "Enter directory name: \c"
read answer
newdir=`grep $answer file_with_dirnames|cut -f2 -d" "`
ls -l $newdir # Other operations can be performed on $newdir
#This will prompt use for dir name.
# Grep will find the line with that name. The cut command
# will cut the desired field (provided the fields are seperated by
# a tab)
# Variable substitution will jam the new dir name into "answer"
--
Family motto: Semper ubi, sub ubi. mail: attmail!pfinkel
"My name is Fink, whaddaya think, I press pants for nothing?"
(Punch line to corny joke that my father always told!)
More information about the Comp.unix.questions
mailing list