LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 12-01-2010, 11:58 AM   #1
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Rep: Reputation: 17
reading unix file permissions into a bash array for processing


Hi,

I would like to read unix file permissions into a bash array for processing but tbh i have no idea how to do this. Then I will check for each individual access right l, d, x etc

I'd be greatful for some pointers.

Thanks
 
Old 12-01-2010, 12:33 PM   #2
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,014

Rep: Reputation: 115Reputation: 115
Use "stat". It kinda sounds like you want to parse the output of ls, but that's a bad idea
 
Old 12-01-2010, 01:13 PM   #3
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Original Poster
Rep: Reputation: 17
Hmm this is on Solaris which does'nt have stat afaik. What would you suggest ? Use an array in BASH / awk ? How do you read the first 7 characters into an array using awk...

Last edited by dazdaz; 12-01-2010 at 05:20 PM.
 
Old 12-01-2010, 07:04 PM   #4
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
Ok. So it is homework and appears that the do wish you to use 'ls -l' (ie the reference to first 7 characters)

Maybe you could show what you have tried and where you are getting stuck?

By the LQ rules no one will do the work for you (as you won't learn that way), but we are more than happy to guide you when stuck
 
Old 12-02-2010, 01:15 PM   #5
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Original Poster
Rep: Reputation: 17
Hi,

I have read in the ls attributes of a file into an array using nawk. I think that using awk might be better than bash for this task...

I think I can see how it would work... All 9 byte's for the permission could be read into another array,
and then processed however I am not entirely sure if I need substr to provide the offset or if there is another method.

If the filename has spaces then this script won't print the full filename, so I need to assign array[filename] $9 to the end of the line. How can I do that in awk ?
I have never seen a filename with a newline... i am not sure how to factor that in but i realise that it's possible.

PS. Coincidentally the script below makes a cleaner formatted Solaris ls, than the native output :-)


Code:
/usr/bin/ls -l | nawk ' {array["perms" ++i]=$1};
                        {array["links" i]=$2};
                        {array["user" i]=$3};
                        {array["group" i]=$4};
                        {array["size" i]=$5};
                        {array["month" i]=$6};
                        {array["day" i]=$7};
                        {array["year" i]=$8};
                        {array["filename" i]=$9};
# END {for (j=1;j<=i;j++) {printf "%7s %4s %10s %10s %10s %4s %4s %5s %-20s\n", array["perms" j],array["links" j],array["user" j],array["group" j],array["size" j],array["month" j],array["day" j],array["year" j],array["filename" j]}}'

END {for (j=1;j<=i;j++) {for (count=1; i<=9; i++) p0=substr(array["perms"],count,1} if p0=="d" then printf "Directory %7s %4s %10s %10s %10s %4s %4s %5s %-20s\n", array["perms" j],array["links" j],array["user" j],array["group" j],array["size" j],array["month" j],array["day" j],array["year" j],array["filename" j]}}'

Last edited by dazdaz; 12-02-2010 at 04:06 PM.
 
Old 12-02-2010, 11:17 PM   #6
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
So you lost me here?? Why have you done all the extra items? I thought we were looking at the permissions?

I am now not sure what you are looking to achieve or have you now found what you are looking for?
 
Old 12-03-2010, 02:49 PM   #7
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Original Poster
Rep: Reputation: 17
Hi Grail, how are you. Thanks for your reply.

Let me explain some more :-))

If a directory, the print an ansi code (colour red for example), if a symbolic link then print blue.

I'm still not confident with the correct awk to process each permission.

Last edited by dazdaz; 12-03-2010 at 04:25 PM.
 
Old 12-04-2010, 02:58 AM   #8
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
So I am guessing (as have not worked on Solaris) that your ls does not have a colour option by default, but you are looking to make your own colourized ls output?

If this is the case maybe we do not need awk at all?? All you really need to know is the first letter at the beginning of permissions (ie d, l, -, etc) and then use a case statement
to apply the appropriate colour.

You could still probably do in awk as well.

Something like:
Code:
#!/bin/bash

NORMAL='\e[0;37m'

while read -r LINE
do
    FILE=false

    case ${LINE:0:1} in
        -)  COLOR=$NORMAL;FILE=true;;
        d)  COLOR='\e[0;34m';;
        l)  COLOR='\e[1;36m';;
        *)  COLOR=$NORMAL;;
    esac

    if $FILE && [[ ${LINE:0:9} =~ x ]]
    then
       COLOR='\e[1;32m'
   fi

    echo -e "$COLOR$LINE$NORMAL"
done< <(ls -l --color=no)
Probably needs tidy up to cope with more things, but you get the idea.

Last edited by grail; 12-04-2010 at 03:23 AM.
 
Old 12-04-2010, 08:12 AM   #9
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Original Poster
Rep: Reputation: 17
Hi. Solaris does not have a colour'ised ls with the OS. There is GNU ls, but it's not always possible to install it (company rules/regulations), and it's nice to have this in a shell function, so any user can run use it or modify as they like.

I like your solution, it's clean, neat and just works (I tested that it works on Solaris 10)

I have been trying to finish this in awk as a learning exercise. I'm getting much closer but not quite there. Right now it prints upto the first directory or 10th file and then quits which is'nt intended. Would you have any suggestions or pointers ?

Code:
#!/bin/bash

/bin/ls -l --color=no | gawk ' {array["perms" ++i]=$1};
                        {array["links" i]=$2};
                        {array["user" i]=$3};
                        {array["group" i]=$4};
                        {array["size" i]=$5};
                        {array["month" i]=$6};
                        {array["day" i]=$7};
                        {array["year" i]=$8};
                        {array["filename" i]=$9};
END {
        for (j=1;j<=i;j++) {
                for (i=1;i<11;i++) {
                        perm=substr(array["perms" j],i,1)
#                       printf "%s %s\n", perm, array["filename" j]
                        if ( perm ~ /d/ ) {
                                colour="\033[0;34m" ; break }
                        if ( perm ~ /l/ ) {
                                colour="\033[0;36m" ; break }
                        else if ( perm ~ /s/ ) {
                                colour="\033[0;36m" ; break }
                        else
                                colour="\033[0;37m"
                                }
                                printf "%s%7s %4s %10s %10s %10s %4s %4s %5s %-20s\n", colour, array["perms" j],array["links" j],array["user" j],array["group" j],array["size" j],array["month" j],array["day" j],array["year" j],array["filename" j]
                                printf "\033[0;37m"
                        }
}'

Last edited by dazdaz; 12-04-2010 at 09:49 AM.
 
Old 12-04-2010, 10:56 AM   #10
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,698

Rep: Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988Reputation: 1988
So you are either going to love or hate this idea ... but here goes, this is how the awk script would look for me:
Code:
#!/usr/bin/awk -f

BEGIN{
    DIR="\033[0;34m"
    EXE="\033[0;32m"
    LINK="\033[0;36m"
    SOCK="\033[0;36m"
    NORM="\033[0;37m"
}

{ colour = NORM }

/^d/{ colour = DIR }
/^l/{ colour = LINK }
/^s/{ colour = SOCK }

$1 ~ /^-.*x/{ colour = EXE }

{ print colour $0 NORM }
Put this in a file called ll.awk and set execution. Run like so to test:
Code:
ls -l --color=no | ./ll.awk
I just find it a little cleaner and easy to change your colours later should you wish
 
Old 12-04-2010, 11:12 AM   #11
dazdaz
Member
 
Registered: Aug 2003
Location: Europe
Distribution: RHEL 6.x, 5.x, Fedora 20, Kubuntu 12.04, Solaris 10,8
Posts: 321

Original Poster
Rep: Reputation: 17
V. nice, thank you :-)
 
Old 12-06-2010, 04:21 PM   #12
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris10, Solaris 11, Mint, OL
Posts: 9,523

Rep: Reputation: 365Reputation: 365Reputation: 365Reputation: 365
Quote:
Originally Posted by dazdaz View Post
Hi. Solaris does not have a colour'ised ls with the OS.
Solaris 11 has it:
http://bugs.opensolaris.org/bugdatab...bug_id=6803941
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash + Reading values(numbers) from a file and storing them into an array SuchANewb Linux - Newbie 5 11-04-2010 09:11 AM
Bash - Reading csv delimited file to array and for further manipulation BLWEGRZYN Programming 1 01-06-2010 10:38 PM
BASH: Reading long filenames into an array using a loop DaneM Programming 12 09-11-2009 08:24 AM
Processing XML file (reading records) lourencojunior Linux - Newbie 2 06-28-2008 02:20 PM
Reading crontab into bash array nutthick Programming 2 05-22-2006 01:44 PM


All times are GMT -5. The time now is 04:36 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration