|
Home > Archive > Unix Shell > October 2006 > listing nondirectories
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
listing nondirectories
|
|
| james19390@yahoo.com 2006-10-25, 7:15 pm |
| Working in GNU bash, version 3.1.17(1)-release
In a directory containing a mix of regular files and subdirectories,
why does this
ls -Fd *[!/]
fail to return any matches?
| |
| Janis Papanagnou 2006-10-26, 1:30 am |
| james19390@yahoo.com wrote:
> Working in GNU bash, version 3.1.17(1)-release
> In a directory containing a mix of regular files and subdirectories,
> why does this
>
> ls -Fd *[!/]
>
> fail to return any matches?
>
Because filenames and directory names are not allowed to contain a
slash. Slashes are handled specifically by Unix; its purpose is to
delimit file and directory components.
Compare the behaviour of these two commands ls */* and ls *[/]*
or ls *\/* (ie. simpler versions of your attempt).
Janis
| |
| Janis Papanagnou 2006-10-26, 1:30 am |
| james19390@yahoo.com wrote about "Subject: listing nondirectories"
> Working in GNU bash, version 3.1.17(1)-release
> In a directory containing a mix of regular files and subdirectories,
> why does this
>
> ls -Fd *[!/]
>
> fail to return any matches?
>
You may want to use find instead
find . -type f -print
(try also option -maxdepth 1)
Janis
| |
| james19390@yahoo.com 2006-10-26, 1:30 am |
|
Janis Papanagnou wrote:
> james19390@yahoo.com wrote about "Subject: listing nondirectories"
>
> You may want to use find instead
>
> find . -type f -print
>
> (try also option -maxdepth 1)
>
> Janis
Thanks
| |
| Geoff Clare 2006-10-26, 1:15 pm |
| james19390@yahoo.com wrote, on Wed, 25 Oct 2006:
> Working in GNU bash, version 3.1.17(1)-release
> In a directory containing a mix of regular files and subdirectories,
> why does this
>
> ls -Fd *[!/]
>
> fail to return any matches?
The / has higher precedence than [...]:
$ mkdir a[!
$ touch a[!/]
$ ls -d *[!/]
a[!/]
$ ls a[!
]
--
Geoff Clare <netnews@gclare.org.uk>
| |
| Spiros Bousbouras 2006-10-26, 7:19 pm |
| james19390@yahoo.com wrote:
> Working in GNU bash, version 3.1.17(1)-release
> In a directory containing a mix of regular files and subdirectories,
> why does this
>
> ls -Fd *[!/]
>
> fail to return any matches?
If you want everything except / then the notation
to use is [^/] not [!/] When you write ls -Fd *[!/]
then the *[!/] part will expand to all the files whose
name ends in either / or ! And since a file's name
cannot contain / it will expand to all the files whose
name ends in !
Apart from that you have the wrong idea of how things
work. When you write ls -Fd *[!/] then the shell will expand
the *[!/] part to the appropriate list of files and then it
will call the ls executable passing it this list of files. Then
ls will print the files adding the appropriate suffix to the
file's name according to the file's type. The main point is that
the matching will take place **first** and the adding of /
at the end of a directory's name will take place **afterwards**.
| |
| Janis Papanagnou 2006-10-26, 7:19 pm |
| Spiros Bousbouras wrote:
> james19390@yahoo.com wrote:
>
>
>
>
> If you want everything except / then the notation
> to use is [^/] not [!/] When you write ls -Fd *[!/]
> then the *[!/] part will expand to all the files whose
> name ends in either / or ! And since a file's name
> cannot contain / it will expand to all the files whose
> name ends in !
I don't think that is correct.
The exclamation mark is a valid negator.
$ ls v*
varlen varset vvv
$ ls v[!v]*
varlen varset
$ ls v[^v]*
varlen varset
Works for me; in ksh, bash, zsh.
Janis
| |
| Spiros Bousbouras 2006-10-26, 7:19 pm |
|
Janis Papanagnou wrote:
> Spiros Bousbouras wrote:
>
> I don't think that is correct.
>
> The exclamation mark is a valid negator.
>
> $ ls v*
> varlen varset vvv
> $ ls v[!v]*
> varlen varset
> $ ls v[^v]*
> varlen varset
>
> Works for me; in ksh, bash, zsh.
Yeah ok , I was careless in my testing. Apparently
! works as a negator in bash but not in tc. ^ works
in both.
| |
|
| Spiros Bousbouras wrote:
> james19390@yahoo.com wrote:
> The main point is that
> the matching will take place **first** and the adding of /
> at the end of a directory's name will take place **afterwards**.
Well, yes and no.
Ksh88(1), at least, has the special case, that if a
pattern ends with slash ("/"), a matching upon a
directory is mandated; however, it's negation (as
contended by this thread) is not implemented, which
is an error of omission.
That is, "*/" will match all directories, but "*[^/]"
(or "*[!/]") does not work.
echo -- */ # just ordinary directories
echo -- .*/ # just dot-directories
echo -- .*/ */ # both
(Warning: some "echo"s will not recognize the "--"
meta-option.)
There is a workaround, though. Assign FIGNORE as
the result of the alternation ("@(...)") of matching
directories, and then match "*" (all files/directories).
The disadvantage is that only in a few implementations
of ksh88 is this special variable implemented and
documented. This is reliably only a ksh93 feature.
>From the manpage:
"FIGNORE: A pattern that defines the set of filenames
that will be ignored when performing filename matching."
I am not as familiar with the situation with bash(1),
and the specific contribution mentioning "^" versus
"!" does not indicate if bash(1) handles the special
case of "/" (instead of "v") well.
=Brian
| |
| Spiros Bousbouras 2006-10-30, 7:30 pm |
| bsh wrote:
> Spiros Bousbouras wrote:
>
> Well, yes and no.
>
> Ksh88(1), at least, has the special case, that if a
> pattern ends with slash ("/"), a matching upon a
> directory is mandated; however, it's negation (as
> contended by this thread) is not implemented, which
> is an error of omission.
>
> That is, "*/" will match all directories, but "*[^/]"
> (or "*[!/]") does not work.
You learn something new every day. I just checked
and tc and bash have the same behaviour.
prompt> ls -bF
E e/ Q q/ R r/ rt T t/ W w/
prompt> echo */
e/ q/ r/ t/ w/
prompt> echo *[^/]
The last line gives "No match" on tcsh and
*[^/] on bash. Should it not give all the
files ? What am I missing ?
> echo -- */ # just ordinary directories
> echo -- .*/ # just dot-directories
> echo -- .*/ */ # both
>
> (Warning: some "echo"s will not recognize the "--"
> meta-option.)
Why do you need -- ?
| |
| Stephane CHAZELAS 2006-10-30, 7:30 pm |
| 2006-10-26, 14:45(+01), Geoff Clare:
> james19390@yahoo.com wrote, on Wed, 25 Oct 2006:
>
>
> The / has higher precedence than [...]:
>
> $ mkdir a[!
> $ touch a[!/]
> $ ls -d *[!/]
> a[!/]
Hi Geoff,
where is that specified?
Only bash gives the output above, debian ash, ksh and pdksh
don't find any file, zsh reports every file.
Note that only zsh supports matching on the file type
thanks to its globbing qualifiers.
ls -d -- *(^/)
or
ls -d -- *(^-/)
to also ommit symlinks to directories.
--
Stéphane
| |
|
| Spiros Bousbouras wrote:
> bsh wrote:
[vbcol=seagreen]
> What am I missing ?
Nothing. It's an error of the interpreter(s).
> Why do you need "--" ?
For commands or builtins that accept (or have even
accepted) command line options, there should/must
be a special option that turns off further options parsing.
What if a command line parameter (that is, not another
option) starts with a dash?
For compiled Unix software tools that use the getopt(3),
getopts(3), or (new) optget(3) library routines, this is a
feature of all of those routines. The corresponding shell
command or builtin built upon the C routines, behave
similarly.
The usual issue seen around C.U.S. once or twice a
year is how to perform an ls(1) on a filename starting
with a dash character. For builtins, what if one tries to
set a dash ("-") as $1? (Old pdksh had this problem).
ls -1 # that is, filename "-1", not option "-1"
The fun starts when the author decides that a builtin
is never going to have options parsing. When bourne
shell became ksh(1), and ksh88's cd (change directory)
builtin got options -- and thus option "--" -- all sorts
of problems started when attempting robust upward
compatibilty with legacy scripts, when "cd -P" did
_not_ mean chdir to directory "-P".... Also, you would
be surprised at how many features of the newest version
of ksh(1) were actually undocumented features of the
previous version.
Echo is especially egregious is this regard; BSD echo
took option -n, and SYS5 echo didn't take any options,
perferring in-line attributes; now there is all sorts of
juggling with workarounds that attempt to utililize both.
The usual idiom is:
# Taylor's 008-echon.sh :
echon() { echo "$*" | tr -d '\n'; }
# another solution :
[[ "$(echo -n)" == "-n" ]] && echon () { echo "$@\c"; } ||
echon () { echo -n "$@"; }
.... and so on, leading David Korn to conclude in his ksh(1)
FAQ at kornshell.com:
"Q12: Why does have print since echo already exists is is
widely used?
"A12: The behavior of echo varies from system to system.
The POSIX standard does not define the behavior of echo
when the first argument beings with a - or when any argument
contains a \ character. This makes echo pretty useless for
use in portable scripts."
A good website that shows the evolution of portability
concerns is Sven Mascheck's site:
"Portable Shell Programming"
http://www.in-ulm.de/~mascheck/various/portability/
http://www.in-ulm.de/~mascheck/vari...ols_issues.html
There are many others, including:
"Porting Shell Scripts"
http://www.microsoft.com/technet/in...hscrpt.mspx#EIC
"UNIX Portability Notes"
http://cr.yp.to/docs/unixport.html
"news:comp.unix.shell - how to write portable shell scripts?"
http://groups-beta.google.com/group...6d06d746e6c5ad7
"Documentation for lintsh"
http://code.dogmap.org/lintsh/
"Shell Command Language -- Migrating from the System V
Shell to the POSIX Shell"
http://www.unix.org/whitepapers/shdiffs.html
=Brian
| |
| Geoff Clare 2006-10-31, 1:21 pm |
| Stephane CHAZELAS <this.address@is.invalid> wrote, on Mon, 30 Oct 2006:
> 2006-10-26, 14:45(+01), Geoff Clare:
>
> Hi Geoff,
>
> where is that specified?
XCU 2.13.3 Patterns Used for Filename Expansion
The rules described so far in Patterns Matching a Single Character
and Patterns Matching Multiple Characters are qualified by the
following rules that apply when pattern matching notation is used
for filename expansion:
1. [...] Slashes in the pattern shall be identified before bracket
expressions; thus, a slash cannot be included in a pattern
bracket expression used for filename expansion. If a slash
character is found following an unescaped open square bracket
character before a corresponding closing square bracket is
found, the open bracket shall be treated as an ordinary
character. For example, the pattern "a[b/c]d" does not match
such pathnames as abd or a/d. It only matches a pathname of
literally a[b/c]d.
> Only bash gives the output above, debian ash, ksh and pdksh
> don't find any file, zsh reports every file.
Looks like a bug in those shells. In ksh it works without the *,
or with a * on the end:
$ ls -d *[!/]
*[!/]: No such file or directory
$ ls -d a[!/]
a[!/]
$ ls -d a[!/]*
a[!/]
so it is getting the precedence right, but when combined with globbing
before the [ it is broken.
--
Geoff Clare <netnews@gclare.org.uk>
|
|
|
|
|