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

Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
NiCKz
  • 63
  • 7
  • **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

2 Answers2

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.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • 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
  • @NiCkz, most likely you edits the script on a Microsoft system and forgot to convert the line endings to Unix format. On Unix-like systems the line delimiter is LF only while it's the 2 characters CR and LF on Microsoft OSes. So Windows files appear to have trailing CR characters on Unix. – Stéphane Chazelas Jun 14 '18 at 17:25
  • That's true, I am on Windows 7. I usually use WinSCP and then open the shell script in Notepad++, since I am not very comfortable with Unix command line or the vi editor. Is that why directory path `^M: not found.` error shows up? But, other than that the shell script I posted looks fine? – NiCKz Jun 14 '18 at 17:40
  • @NiCKz, it's OK except you forgot to check for success of `cd`. Change to `cd /dir || exit`. Also here you might as well do everything in perl. Change the shebang to `#! /usr/bin/perl`, and do the `cd` with `chdir "/dir" || die "cd: $!\n";` followed by the rest of the `perl` code. – Stéphane Chazelas Jun 14 '18 at 17:54
  • You are Amazing! I changed `#!/usr/bin/sh` to `#! /usr/bin/ksh` and also changed `cd /dev/product/jobs` to `cd /dev/product/jobs || exit` and it's working fine. Thanks so much for all your help, really appreciate it :) I'll post the final update to the question so that others can find it helpful. – NiCKz Jun 14 '18 at 22:51
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

ypouplard
  • 11
  • 4
  • 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
  • I spent a part of my Sunday to read all the HP-UX manuals downloaded the day before, without finding any **stat** line command for regular files — I was very surprised. Sorry for the poor help :-( – ypouplard Jun 21 '18 at 14:37