LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Extracting File Names from Long Listing of Directory in UNIX (https://www.linuxquestions.org/questions/programming-9/extracting-file-names-from-long-listing-of-directory-in-unix-829596/)

Hi_This_is_Dev 08-31-2010 02:36 PM

Extracting File Names from Long Listing of Directory in UNIX
 
Hi,


I am calling a Shell Script, namely "scanTmp.sh" from within a PHP script using exec().


The Shell Script, in fact, has only one task to perform:

[CODE=php]contents=`ls -ltr /tmp | tail -n +2`[/CODE]

The value of the variable "contents" is then reutrned to the PHP script. I am displaying the contents using the array which is used in the exec() function to hold the output of the shell script.

The problem that I am now facing is: How to extract only the name part of the directory / file from the output such as:

[CODE=php]-rw-r--r-- 1 root root 0 Aug 30 16:50 2_b
-rw-r--r-- 1 root root 0 Aug 30 16:50 2_a
-rw-r--r-- 1 root root 0 Aug 30 16:50 1_d
-rw-r--r-- 1 root root 0 Aug 30 16:50 1_c
-rw-r--r-- 1 root root 0 Aug 30 16:50 1_b
-rw-r--r-- 1 root root 0 Aug 30 16:50 1_a
-rw-r--r-- 1 root root 133 Aug 31 19:52 August.txt
-rw-r--r-- 1 root root 1963 Aug 31 20:30 2010 Programme[/CODE]

It is also important that file / directory name may contain blank spaces:

[CODE=php]-rw-r--r-- 1 root root 1963 Aug 31 20:30 2010 Programme[/CODE]

Here, the file name is: "2010 Programme".


Well, the purpose of extracting only file names is to enable the functionality of displaying the contents of that file after passing the file name as the parameter to another PHP script. We can create hyper links while listing the directory contents.

Please note that the solution I want is in PHP and not in Shell Script as the functionality is to be provided in the PHP Script while displaying the contents of the array that holds the output of the result returned by the function exec().

Any ideas?

Sergei Steshenko 08-31-2010 02:58 PM

PHP has both 'opendir' and 'readdir', as well as 'stat'. so why do you need the shell script in the first place ? I.e. use these functions and create whatever output you like in the first place, rather than adjusting output you do not like.

crts 08-31-2010 03:02 PM

Hi,

Code:

ls -ltr /tmp | tail -n +2|awk -F: '{$1=""; print gensub(/^..../,"","1",$0) }'
This assumes that your first colon is the one in the time field.

Hi_This_is_Dev 08-31-2010 08:38 PM

Displaying Only File and Directory Names Line By Line
 
Quote:

Originally Posted by crts (Post 4083934)
Hi,

Code:

ls -ltr /tmp | tail -n +2|awk -F: '{$1=""; print gensub(/^..../,"","1",$0) }'
This assumes that your first colon is the one in the time field.

Hi Carts!

You have really found out or devised a good method which replaces the following simple command

Code:

ls -1 bin
cleanup.sh
exit.sh
host.sh

Note: That is digit 1 and not l after ls -


Code:

ls -ltr bin | tail -n +2|awk -F: '{$1=""; print gensub(/^..../,"","1",$0) }'
cleanup.sh
exit.sh
host.sh

Well, the awk... part is really good to understand how we can come up with different ways of doing the same thing and different things as well.

But my question is different from what you understood. The result of

ls -l is to be passed to the PHP Script which displays the information keeping it intact.

But I want to extract the file name part from every line in the PHP Script.

Let's say this is being passed to the PHP Script:

Code:

-rw-r--r-- 1 root root 14236 Aug  4 11:49 msg.txt
and it is being displayed by the PHP Script. But now I want to extract the file name part so that I can fetch its contents on demand.

Sergei Steshenko 08-31-2010 08:43 PM

Quote:

Originally Posted by Hi_This_is_Dev (Post 4084212)
...
Let's say this is being passed to the PHP Script:

Code:

-rw-r--r-- 1 root root 14236 Aug  4 11:49 msg.txt
...

Is there anything wrong in my proposal in http://www.linuxquestions.org/questi...6/#post4083928 ?

Hi_This_is_Dev 08-31-2010 08:50 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4083928)
PHP has both 'opendir' and 'readdir', as well as 'stat'. so why do you need the shell script in the first place ? I.e. use these functions and create whatever output you like in the first place, rather than adjusting output you do not like.


Well, I have not tried the "stat" function in PHP. But I have done this before:

Code:

<?php

        $dir = "test";

        $dh = opendir($dir);

        echo "<ul>";

        if($dh) {

                $file = readdir($dh);

                      while ($file) {

                        echo "<li>";
       
                        if(filetype($file) == "dir") {

                                echo "<font color=RED>[DIRECTORY]</font> ";
                        }       

                        else {

                                echo "<font color=GREEN>[FILE]</font> ";

                        }
 
                        echo "<a href='" . $file . "'>" . $file . "</a><br />";

                        echo "</li>";

                        $file = readdir($dh);
                      }

                closedir($dh);
        }

        echo "</ul>";

?>


And here is its output:

Code:

[DIRECTORY] .

[DIRECTORY] ..

[FILE] var1.php

Nice? :)



Okay, my primary purpose is to learn and explore. That is why I tried to see if I could easily interact with a Shell Script from within a PHP Script. It's working fine. But I want to handle the output returned by the Shell Script program according to my requirement.

In other words, sometimes or often we may need to handle the output returned by a command or program found in UNIX / Linux when we are doing certain tasks through a Web Interface.

I got the idea of displaying file names along with the associated information from the web interface I am using in my project (within the company). When we click a log file name, its contents extracted as per the requirement and are then displayed in a columnar fashion. Isn't it great? :)

Sergei Steshenko 08-31-2010 09:05 PM

Quote:

Originally Posted by Hi_This_is_Dev (Post 4084219)
Well, I have not tried the "stat" function in PHP. But I have done this before:

Code:

<?php

        $dir = "test";

        $dh = opendir($dir);

        echo "<ul>";

        if($dh) {

                $file = readdir($dh);

                      while ($file) {

                        echo "<li>";
       
                        if(filetype($file) == "dir") {

                                echo "<font color=RED>[DIRECTORY]</font> ";
                        }       

                        else {

                                echo "<font color=GREEN>[FILE]</font> ";

                        }
 
                        echo "<a href='" . $file . "'>" . $file . "</a><br />";

                        echo "</li>";

                        $file = readdir($dh);
                      }

                closedir($dh);
        }

        echo "</ul>";

?>


And here is its output:

Code:

[DIRECTORY] .

[DIRECTORY] ..

[FILE] var1.php

Nice? :)



Okay, my primary purpose is to learn and explore. That is why I tried to see if I could easily interact with a Shell Script from within a PHP Script. It's working fine. But I want to handle the output returned by the Shell Script program according to my requirement.

In other words, sometimes or often we may need to handle the output returned by a command or program found in UNIX / Linux when we are doing certain tasks through a Web Interface.

I got the idea of displaying file names along with the associated information from the web interface I am using in my project (within the company). When we click a log file name, its contents extracted as per the requirement and are then displayed in a columnar fashion. Isn't it great? :)

What did you mean writing

Code:

while ($file)
?

What kind of thing (string or array) is $file in the above context ?

How many times

Code:

$file = readdir($dh);
is supposed to be executed ?

Sergei Steshenko 08-31-2010 09:16 PM

Quote:

Originally Posted by Hi_This_is_Dev (Post 4084219)
...
if(filetype($file) == "dir") {

...

The item in red is apparently wrong, and it's a typical error with 'readir' - you are not in $dir directory, so you are checking $file in your CWD.

I am not a PHP guy; in Perl it is

Code:

my $file_prefixed_with_dir = "$dir/file";
if(-d $file_prefixed_with_dir)
  {
  print "$file_prefixed_with_dir is a directory\n";
  }
else
  {
  print "$file_prefixed_with_dir is NOT a directory\n";
  }

, i.e. you need to construct the correct path to item to be stat'ed.

ghostdog74 08-31-2010 09:46 PM

here's an example of what you want to do in PHP
Code:

<?php
$dir = "/path";
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false) {
            $ftype=filetype($dir . $file); # or is_file(), is_dir()
            $mtime = filemtime($file); #you can use stat , but this is much easier
            # now you can collect the mtime and file name and put into array.
            # this array can be sorted and you can get the last 10 elements ( ie your tail -10 )
            if ( $ftype == "file" ) {
                echo "file: $file\n";
            } elseif( $ftype == "dir" ) {
                echo "Directory: $file\n";
            }
        }
        closedir($dh);
    }
}
?>

If in doubt, always go to the PHP documentation site.

Hi_This_is_Dev 08-31-2010 09:56 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4084233)
What did you mean writing

Code:

while ($file)
?

What kind of thing (string or array) is $file in the above context ?

How many times

Code:

$file = readdir($dh);
is supposed to be executed ?



$file = readdir($dh);

Reads the next content / file from the specified directory that the Directory Handler $dh points to.

Inside the loop, the last statement, as given above, fetches the next file name. On failure, readdir() returns false. When it is false, the while loop while... is exited.
  • From the PHP Manual:

Code:

readdir — Read entry from directory handle
  1. Description

string readdir ([ resource $dir_handle ] )
Returns the filename of the next file from the directory. The filenames are returned in the order in which they are stored by the filesystem.
  1. Return Values

Returns the filename on success, or FALSE on failure.



$file is a variable that is assigned the value of the statement readdir($dh). On success, it is the next file name, or else boolean false.

So, the while loop keeps executing as long as the $file doesn't contain a boolean false value.

I have written and run that PHP script and tested on Windows XP (IIS). I will check it on Linux as well.

ghostdog74 08-31-2010 10:10 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4084233)
What did you mean writing

Code:

while ($file)
?

What kind of thing (string or array) is $file in the above context ?

that while loop should be written this way (as documented)
Code:

while (false !== ($file = readdir($handle))) {
        echo "$file\n";
}


Hi_This_is_Dev 08-31-2010 10:11 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4084243)
The item in red is apparently wrong, and it's a typical error with 'readir' - you are not in $dir directory, so you are checking $file in your CWD.

I am not a PHP guy; in Perl it is

Code:

my $file_prefixed_with_dir = "$dir/file";
if(-d $file_prefixed_with_dir)
  {
  print "$file_prefixed_with_dir is a directory\n";
  }
else
  {
  print "$file_prefixed_with_dir is NOT a directory\n";
  }

, i.e. you need to construct the correct path to item to be stat'ed.


First, thanks for the Perl version. :)


The statement below:

PHP Code:

    $dir "test"

assigns the literal name test to the variable $dir. test is the directory found in the CWD, yes, you're right. So, the contents of the test directory would be displayed, and not of the CWD.

I tested it with:

PHP Code:

    $dir "../wwwroot"

and the script then displayed the contents / files of the current directory incuding, of cuorse, the directory "test" which is in the "../wwwroot/test" and of the other directories found in the current directory- provided that we click those directory names to see what they contain.

This statement creates a pointer or handler to the specified directory that we are going to work with:

PHP Code:

$dh opendir($dir); 

The statement below:

PHP Code:

if(filetype($file) == "dir") {...} 

checks for the type of the file or content found in the specified directory.

filetype() returns file and dir values as string. So, if the return value is "dir" then branch accordingly.

Okay, we have is_dir() and is_file() functions also to know whether a given (file) name is a regular directory or a regular file. :)

Yes, you're right, we can give the absolute or relative path as well.



Well, you know Perl so I may bug you sometimes when I begin to learn Perl. ;)

Sergei Steshenko 08-31-2010 10:13 PM

Quote:

Originally Posted by Hi_This_is_Dev (Post 4084288)
$file = readdir($dh);

Reads the next content / file from the specified directory that the Directory Handler $dh points to.

Inside the loop, the last statement, as given above, fetches the next file name. On failure, readdir() returns false. When it is false, the while loop while... is exited.
  • From the PHP Manual:

Code:

readdir — Read entry from directory handle
  1. Description

string readdir ([ resource $dir_handle ] )
Returns the filename of the next file from the directory. The filenames are returned in the order in which they are stored by the filesystem.
  1. Return Values

Returns the filename on success, or FALSE on failure.



$file is a variable that is assigned the value of the statement readdir($dh). On success, it is the next file name, or else boolean false.

So, the while loop keeps executing as long as the $file doesn't contain a boolean false value.

I have written and run that PHP script and tested on Windows XP (IIS). I will check it on Linux as well.

But your code contradicts the item in bold - you do not call readdir in a loop:

Code:

        if($dh) {

                $file = readdir($dh);

                      while ($file) {


Hi_This_is_Dev 08-31-2010 10:28 PM

Quote:

Originally Posted by ghostdog74 (Post 4084297)
you always advise people to RTFM, but you don't do it yourself?
that while loop can be written this way (as documented)
Code:

while (false !== ($file = readdir($handle))) {
        echo "$file\n";
}


Hi,


I saw that form of the while loop in the manual of PHP. Yes, you're right.

By the way, what is RTFM? :)

Sergei Steshenko 08-31-2010 10:30 PM

Quote:

Originally Posted by Hi_This_is_Dev (Post 4084319)
...
By the way, what is RTFM? :)

The politically correct explanation is: "Read The Fine manual".


All times are GMT -5. The time now is 06:24 AM.