[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Determination of file lists from selected folders without returning

From: Kaz Kylheku (Coreutils)
Subject: Re: Determination of file lists from selected folders without returning directory names
Date: Mon, 17 Jul 2017 11:09:40 -0700
User-agent: Roundcube Webmail/0.9.2

On 17.07.2017 10:25, SF Markus Elfring wrote:

The tool “ls” supports the filtering of directory contents.

No, it actually doesn't. In a shell command like

  ls *.txt

it is actually the shell which performs the *.txt filename expansion,
before the ls program is executed. That program receives all of the
file names as individual arguments, rather than the original pattern.

If you just want the names themselves, you can simply do:

  echo *.txt

One advantage of this is that it avoids the limitations on the
size of the argument vector that can be passed to a child process,
because echo is built-in (if we're talking about GNU Bash, which
is reasonable, given that we're in the GNU Coreutils list.)

Iterating over the matching names is possible using the for syntax:

  for x in *.txt ; do
    commands ...

That also avoids limitations on argument passing since it is all
built-in syntax.

A corresponding result could be achieved by using a subshell (which I would like to avoid for this use case) for a command like “(cd ${my_dir} && ls *txt)”.

If you want to capture these strings into a variable, you can't really
avoid a sub-process. For instance simply doing:

   names=$(echo *txt)

involves a sub-process for the command substitution. Since it is echo,
it could be optimized. I just checked though; bash 4.3.48 is forking
a child process for this. So there is hardly much additional disadvantage
from doing:

   names=$(cd; echo *txt)

that just adds a chdir() system call to the child script.

If the goal is to just dump the names on standard output without the
directory prefix, it can be done like this:

   for name in dir/*txt ; do
     echo ${name#dir/}

this involves no forking of a child process.

To get them on the same line as with echo:

   for name in dir/*txt ; do
     printf "%s " "$name"
   echo # emit final newline

reply via email to

[Prev in Thread] Current Thread [Next in Thread]