Listing files in a particular format

Hi,

My unix version is as follows:

uame -a

HP-UX server-name B.11.11 U 9000/800 2329770924 unlimited-user license

I just want to get file listing is a particular format listed below.

name  permission set(octal)  size  date (mon dd, yyyy)

I am trying to use the following command.

ll | egrep -v '^d' | awk '{ printf "%-29s\t\t%s\t%5s\t\t%s %s,%s\n", $9,$1,$5,$6,$7,$8 }'

But its giving me output like follows-

a.out                                   -rw-------          0           Aug 5,06:55

While the required output is

a.out                                   600          0           Aug 5, 2011

Also its giving me a 'total' line in the beginning while using above given command. I also don't want that line in my output.

Please help me achieve output in desired format.

Many thanks,
Manu

ll | awk ' !/^d/ { if(NR>1) {printf "%-29s\t\t%s\t%5s\t\t%s %s,%s\n", $9,$1,$5,$6,$7,$8} }'

better to post your ls command output and the required output format

Thanks.

Your code removed the first line, where total blocks are written.

Please also help me achieving file creation date in mon dd, yyyy format instead of mon dd hh:mm format.

Thanks.

A clue to get the year!,

if the file is created on the current year, then the file timestamp will be shown in hh:mm format.

So, try something like this:

 
ls -l | awk '{$(NF-1)=$(NF-1)~/:/?"2011":$(NF-1);print}'

You have to add the above code in your requirement.

Hi Panyam,

Thanks for your consideration.

But it's not always true, that if file is created only in the current year, then only time will be show.

Consider the case that today is "2nd Jan 2011", and file is created on "29th Dec 2010". Year has been changed since the time of file creation (2010 to 2011). But still it will show the date in dd mon hh:mm (29 Dec 3:54) format. Kindly consider this case as well.

Regards,
Manu

Manu,

If you post the ls command output and the required output format, then you can get answers soon.

Always give the clear input and output format. :slight_smile:

Hello,

I'm sorry I did not read it fully. Indeed, it's not creation time but modified time.

man ls , gives

 
If the time of last modification is greater than six months ago, or any time in the future, the year is substituted for the hour and minute of the modification time.

So, need to find a logic here to get the years!!!.

Hi,

I think I have clearly stated my requirements. But if still required the output to make the things more clear, I am posting it as below--

Right now my output is like below-

ll | awk ' !/^d/ { if(NR>1) {printf "%-29s\t\t%s\t%5s\t\t%s %s,%s\n", $9,$1,$5,$6,$7,$8} }'

a.out                                   -rw-------          0           Aug 5,06:55
dir_str.txt                             -rw-------         35           Aug 19,10:23
dont_make_test                          ----------          0           Aug 23,10:03
get_dir_stru.sh                         -rwx------        599           Aug 5,11:02
mm                                      -rwx------         85           Aug 23,09:34

But he output I want should be like this

a.out                                   600          0           Aug 5, 2011
dir_str.txt                             600         35           Aug 19, 2011
dont_make_test                          000          0           Aug 23, 2011
get_dir_stru.sh                         700        599           Aug 5, 2011
mm                                      700         85           Aug 23, 2011

And I am sorry Panyam that I mentioned "creation time", yes it's modification time.

Thanks.

Hello,

I'm sorry but I was not much helpful. I searched few things in the forum and found this below useful.

 
#!/usr/bin/ksh
typeset -Z2 d m
Jan=1 Feb=2 Mar=3 Apr=4 May=5 Jun=6 Jul=7 Aug=8 Sep=9 Oct=10 Nov=11 Dec=12
date "+%Y %m" | read year month
for i in `ls -l|awk '!/^d/{print $NF}` ; do
        line=$(ls -dl $i)
        line=${line##+([! ])+([ ])}
        line=${line##+([! ])+([ ])}
        line=${line##+([! ])+([ ])}
        line=${line##+([! ])+([ ])}
        line=${line##+([! ])+([ ])}
        set -A stamp $line
        d=${stamp[1]}
        eval m=\$${stamp[0]}
        y=${stamp[2]}
        ((${#y} != 4)) && ((y=year-(m>month)))
        echo $i ${stamp[0]} $d","$y
done
exit 0
 

You might need to figure it out on how to add file permissions and other fields to the output as required.

Hi Panyam,

I forget to mention, my shell is 'sh', so will the code given by you will work on that shell?

Thanks,
Manu

Try this and see if returns the desired output:

ll|awk -v "year=`date '+%Y'`" '$8!~":"{if(NR>1)printf"%-29s\t\t%s\t%5s\t\t%s %s,%s\n", $9,$1,$5,$6,$7,$8} {if(NR>1)printf"%-29s\t\t%s\t%5s\t\t%s %s,%s\n",  $9,$1,$5,$6,$7, year}'

Hehe,

This is not the exact solution. I am not that much efficient in Unix coding. But by seeing your code, I came to know, that you have searched : in $8 parameter and if it not found, then you printed $8 as it is (as it will be already a year format) and if its found, you replaced $8 with current year (that is WRONG, we need to compare the months as well in that case, if month of file modification is greater than the current month of the current year, then we need to do year=year-1 else year=year). How this will help you (eventually me :slight_smile: ) to write a code for that.

I appreciate your efforts. But whatever you have done can be done by the code below as well--

ll | awk -v "yr=`date '+%Y'`" ' !/^d/ { if(NR>1) {printf "%-29s\t\t%s\t%5s\t\t%s %s,", $9,$1,$5,$6,$7}; if(index($8,":")==3) { print yr } else { print $8 
} }'

Thanks.

Can you past a line from ls that you think the awk code will not work against? i.e paste a line from your ls output where "month of file modification is greater than the current month of the current year"? Maybe I can modify the logic.

Well, for that I need to change the date/time of the system, for that privilidges not granted to me.

Just set your system date to '29-Dec-2010', make a file, now again set your date to '2-Jan-2011', now execute your command. Let me know if your code work perfectly.

Regards,
Manu

---------- Post updated 08-24-11 at 01:16 AM ---------- Previous update was 08-23-11 at 10:28 PM ----------

#!/bin/sh
ll | awk -v "yr=`date '+%Y'`" -v "mnth=`date '+%m'`" 'BEGIN { split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec", MON, "|"); for(N=1; N<=12; N++) I[MON[N]]=N; } !/^d/ { if(NR>1) {printf "%-29s\t\t%s\t%5s\t\t%s %s,", $9,$1,$5,$6,$7}; if(index($8,":")==3) { if(I[$6]>mnth) { print yr-1 } else { print yr }} else { print $8 } }'

The above has fulfilled my purpose.

Thanks all for your time and support.

Hello Manu,

I'm more than happy to see that the code worked for you.

Here is a bit modifed version of your code , which gives the permission in the needed format.

 
 
#!/bin/sh
ll | awk -v "yr=`date '+%Y'`" -v "mnth=`date '+%m'`" 'BEGIN { split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec", MON, "|"); for(N=1; N<=12; N++) I[MON[N]]=N; a["---"]=0;a["--x"]=1;a["-w-"]=2;a["-wx"]=3;a["r--"]=4;a["r-x"]=5;a["rw-"]=6;a["rwx"]=7}
function val(str)
{
u=substr(str,2,3);
g=substr(str,5,3);
o=substr(str,8,3);
r=aa[g]a[o]
return r
} !/^d/ { if(NR>1) {printf "%-29s\t\t%s\t%5s\t\t%s %s,", $9,val($1),$5,$6,$7}; if(index($8,":")==3) { if(I[$6]>mnth) { print yr-1 } else { print yr }} else { print $8 } }'

Your requirement definetly helped us in inproving our skills!!!