LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   sed: transforming 'ls-laR' output into a list with absolute paths (https://www.linuxquestions.org/questions/linux-newbie-8/sed-transforming-ls-lar-output-into-a-list-with-absolute-paths-4175539710/)

schedar 04-14-2015 02:25 PM

sed: transforming 'ls-laR' output into a list with absolute paths
 
Hello, this is my first post :)
First i would like to thank you all for answering other people questions because I've been able to learn from the forum a lot.

I need your help with something.
I have standard output from 'ls -laR /etc' command which looks like this:
Code:

/etc/X11/xorg.conf.d:
total 4
drwxr-xr-x. 2 root root  29 Apr  1 00:46 .
drwxr-xr-x. 5 root root  54 Apr  1 00:43 ..
-rw-r--r--. 1 root root 232 Apr  1 00:46 00-keyboard.conf

/etc/xdg:
total 12
drwxr-xr-x.  4 root root  36 Apr  1 00:43 .
drwxr-xr-x. 87 root root 8192 Apr 12 13:53 ..
drwxr-xr-x.  2 root root    6 Jun 10  2014 autostart
drwxr-xr-x.  2 root root  17 Apr  7 01:25 systemd

by using sed command:
Code:

sed -e '/./!d' -e '/^total/d' -e '/\.$/d' -e 's/:$/\//' list.txt
I have transformed it to the following form:

Code:

/etc/X11/xorg.conf.d/
-rw-r--r--. 1 root root 232 Apr  1 00:46 00-keyboard.conf
/etc/xdg/
drwxr-xr-x.  2 root root    6 Jun 10  2014 autostart
drwxr-xr-x.  2 root root  17 Apr  7 01:25 systemd

and now I would like to achieve absolute paths at the end of each row

Code:

-rw-r--r--.  1 root root  232 Apr  1 00:46 /etc/X11/xorg.conf.d/00-keyboard.conf
drwxr-xr-x.  2 root root    6 Jun 10  2014 /etc/xdg/autostart
drwxr-xr-x.  2 root root  17 Apr  7 01:25 /etc/xdg/systemd


How do I join(merge) filenames with corresponding absolute path to their parent directory?



I know how to extract filenames using awk and get this:
Code:

00-keyboard.conf

autostart
systemd

but I don't know what to do next. Should I use some hitech sed option or go for loop or try with arrays? Help. Heeeelp :)

schneidz 04-14-2015 02:42 PM

your probably better off learning how to print with find. heres an e.g.:
http://www.linuxquestions.org/questi...1/#post5343834

Lnthink 04-14-2015 02:42 PM

That's a pretty big request, as there's no telling how many directories deep that the "ls -laR" command will go.
You can get the same output that you're going for with:

find /etc -type f -exec ls -al {} \;

That will give you what you're looking for, a directory listing of all the /etc files, and their complete path to root, and their full "ls -al" attributes, but for files only (not directories themselves, only their contents).

If you want to include symbolic links, etc. as well as files - then I'd just get everything that's not a directory...

find /etc ! -type d -exec ls -al {} \;

schedar 04-14-2015 03:27 PM

Thanks guys. I forgot to say that I know "find", but it's not me whose generating input file in this form.
This kind of file is a snapshot of permissions from few years back and I need to compare it with current ACLs on the system.
So still looking for an idea for converting this "ls -laR" kind of file to "find" like file.

allend 04-14-2015 05:56 PM

On your transformed sample
Code:

/etc/X11/xorg.conf.d/
-rw-r--r--. 1 root root 232 Apr  1 00:46 00-keyboard.conf
/etc/xdg/
drwxr-xr-x.  2 root root    6 Jun 10  2014 autostart
drwxr-xr-x.  2 root root  17 Apr  7 01:25 systemd

this awk code seems to achieve what you want.
Code:

awk '/^\//{x=$0;next}/[^/]/{print $1,$2,$3,$4,$5,$6,$7,$8,x $9}'

schedar 04-14-2015 06:12 PM

OMG this is fantastic. Thank you! You have convinced me to learn awk :)
I need to be honest with you. I have not been just waiting for solution for 3 hours. I've been trying to solve this... and I did (to my surprise).
Your code much better however.

Anyway just for the record here's what I got:
Code:

#!/bin/bash

ACL_IN=$1                      #input file should be an output from "ls -laR" command
ACL_TMP0="/tmp/aclove0.tmp"
ACL_TMP1="/tmp/aclove1.tmp"


# create empty temp files
>$ACL_TMP0
>$ACL_TMP1


sed -e '/./!d' -e '/^total/d' -e '/\.$/d' -e 's/:$/\//' $ACL_IN > $ACL_TMP0

while read line
  do
    ROW=$line
    [ ${ROW:0:1} == '/' ] && PREFIX=$ROW && continue
    echo ${PREFIX}" "${ROW} >> $ACL_TMP1

  done < $ACL_TMP0

awk '{print $2,$4,$5,$1$10}' $ACL_TMP1


syg00 04-14-2015 06:58 PM

You could of course do all that clean-up work in awk as well, and not need the temp files.
Happy learning - awk is very flexible. Lots of knowledgeable people here to help when you run into brick walls.


All times are GMT -5. The time now is 02:05 PM.