4

I am on HP-UX B.11.11 OS. My requirement is to display a list of directories only and the last modified time format should be DD-MON-YYYY HH:MI:SS AM/PM. I am able to get the list using either

    ls -lF | grep /

OR

    ls -ld -- */

but I am unable to set the time format as I want. The --full-time or --time-style parameter doesn't work in HP-UX, and HP-UX doesn't have stat as well.

Questions:

  1. Primary Requirement: Could anyone please provide me a script to display the list of all the directory names (not files) under current directory and the last modified timestamp in the format mentioned above? I don't need the owner name, group name, size, permissions etc.

  2. Is there any other way to display this information without using C or Perl, by just using standard commands and parameters?

  3. I was wondering how is WinSCP able to display the full date/time format in the UI ? Anyone knows what command it uses internally to display the directory contents in the UI?

Any help is appreciated. Thanks.

UPDATE (edits below only):
So, Stéphane Chazelas's answer with perl script worked perfectly. Now, I am trying to convert it into a shell script, but I am getting errors while executing it. I have saved the shell script dir_list.sh under /dev/scripts/. Could you please help where I am going wrong?

#!/usr/bin/sh
# dir_list.sh : Generate a comma separated directory list with last modified timestamp
# Navigate to the directory where listing is required
cd /dev/product/jobs
# Execute Perl script
/usr/bin/perl -MPOSIX -MFcntl -MFile::stat -le '
  setlocale(LC_TIME, "C");
  for (<*>) {
    $s = lstat $_ or die "$_: $!\n";
    print "$_," . uc(strftime("%d-%b-%Y %I:%M:%S %p", localtime $s->mtime))
      if S_ISDIR($s->mode)
  }'
exit 0

ERROR MESSAGE
Please note that I tried #!/usr/bin/sh as well, but it failed with same error message: interpreter "/usr/bin/sh" not found

$ ./dir_list.sh
interpreter "/bin/sh" not found
file link resolves to "/usr/bin/sh"
ksh: ./dir_list.sh:  not found

Final Update : RESOLVED - Solution Below

I created a Unix shell script dir_list.sh which when called ( $ ./dir_list.sh ) searches within the target folder specified in the script and displays the folder names along with its associated timestamp as a comma-separated records

#! /usr/bin/ksh
# dir_list.sh : Generate a comma separated directory list with last modified timestamp
#
# Navigate to the Target Directory
cd /dev/product/jobs || exit
#
# Execute Perl script to format the output
/usr/bin/perl -MPOSIX -MFcntl -MFile::stat -le '
  setlocale(LC_TIME, "C");
  for (<*>) {
    $s = lstat $_ or die "$_: $!\n";
    print "$_," . uc(strftime("%d-%b-%Y %I:%M:%S %p", localtime $s->mtime))
      if S_ISDIR($s->mode)
  }'
#
exit 0

Thanks to Stéphane Chazelas for all your help! :)

2
  • Another Update: I was able to use sh dir_list.sh but it doesn't provide the output in the target directory (says directory path ^M: not found.). It shows the output only from the directory from where I am executing the script, in this case /dev/scripts. Is there a way to specify output only in the target directory mentioned in shell script?
    – NiCKz
    Jun 14, 2018 at 16:40
  • Answers belong in answers, not in questions. This WWW site does not do things the "RESOLVED" way.
    – JdeBP
    Jun 15, 2018 at 10:32

2 Answers 2

3

Unless GNU utilities are installed, your best bet is probably perl on those traditional systems:

perl -MPOSIX -MFcntl -MFile::stat -le '
  setlocale(LC_TIME, "C");
  for (<*>) {
    $s = lstat $_ or die "$_: $!\n";
    print "$_ " . uc(strftime("%d-%b-%Y %I:%M:%S %p", localtime $s->mtime))
      if S_ISDIR($s->mode)
  }'

That's perl's interface to the standard POSIX lstat() system call that retrieves file metadata and strftime() function to format dates.

See perldoc POSIX, perldoc -f lstat, perldoc -f stat, man lstat, man strftime for details. We use the C locale for LC_TIME so we get English month names and PM/AM regardless of the preferences of the user.

If zsh is installed:

zsh -c 'zmodload zsh/stat
        LC_ALL=C stat -nA times -LF "%d-%b-%Y %I:%M:%S %p" +mtime -- *(/) &&
          for f t ($times) printf "%s\n" "$f: ${(U)t}"'

Above, we're using perl's uc() and zsh's ${(U)var} to convert the timestamps to uppercase. On GNU systems, you could have used %^b for a all-uppercase month abbreviation, but it doesn't look like it's available on HP/UX.

9
  • Thanks so much Stephane.. Exactly what I wanted and worked at the first go! :) If you don't mind, could you please explain or send me a link which provides more info on each of those functions and parameters used? I am new to Unix and Perl.
    – NiCKz
    Jun 14, 2018 at 13:09
  • I edited the script to make the output comma-separated. Could you please tell me how can I get the month in all caps, I tried with %B, but it shows the full month name instead of capitalizing it. Also, how can I convert it into a Shell script (dir_list.sh) to show the all the folders within the directory /dev/product/jobs/
    – NiCKz
    Jun 14, 2018 at 13:17
  • Sorry, forgot to mention that the Perl script worked for me, and not the second one. I guess zsh is not installed.
    – NiCKz
    Jun 14, 2018 at 13:25
  • @NICKz, see edit Jun 14, 2018 at 15:43
  • Thanks Stephane, that worked! I am now trying to create a shell script but running into issues. I edited my question to include an Update, since I wasn't able to post the whole thing as a comment.
    – NiCKz
    Jun 14, 2018 at 16:22
0

find . -type d -exec stat {} \; is the usual Unix System V way. It seems that stat becomes fstat on HP-UX, so the command becomes find . -type d -exec fstat {} \;

Depending of your requirements, you may have to pipe the output in awk (or nawk or gawk) to get exactly what you expect.

Ref: http://hpux.connect.org.uk/hppd/hpux/Shells/fstat-1.0/man.html

6
  • Thanks. I guess stat is not available as a standard install in HP-UX, but I could be wrong. I was executing the above, and it didn't give me any errors but it started scanning within subdirectories which I don't want. Maybe, there is a way to specify only a particular directory and also not to search within subdirectories.
    – NiCKz
    Jun 14, 2018 at 16:46
  • if there is an "iostat" command (specialized for IOs), maybe "stat" has a longer name (fstat ? something else ?) but I can't imagine a Unix without a "stat" command — even Mac OSX which is BSD has a "stat" !!!
    – ypouplard
    Jun 14, 2018 at 17:06
  • can you try (for bin & sbin): find / -type d -name bin -exec ls {}/*stat* \; 2>/dev/null (or something close if it doesn't work). I long to know the answer :-)
    – ypouplard
    Jun 14, 2018 at 17:06
  • Will be back tomorrow only, sorry :-)
    – ypouplard
    Jun 14, 2018 at 17:10
  • I tried the above but didn't work for me, it started navigated through all the directories. The solution provided by @Stéphane worked for me. Appreciate your help :)
    – NiCKz
    Jun 14, 2018 at 23:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .