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! :)

  • 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 '18 at 16:40
  • Answers belong in answers, not in questions. This WWW site does not do things the "RESOLVED" way. – JdeBP Jun 15 '18 at 10:32
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.

  • 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 '18 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 '18 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 '18 at 13:25
  • @NICKz, see edit – Stéphane Chazelas Jun 14 '18 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 '18 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

  • 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 '18 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 '18 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 '18 at 17:06
  • Will be back tomorrow only, sorry :-) – ypouplard Jun 14 '18 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 '18 at 23:04

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.