ls in specific columns

Hello,

i need to get the ls output in 2 columns.1st column the directories and 2nd the files...
Also each column must be sorted by time...

For example if the >>ls command gives me this :

/dir2   /dir   /dir1
/dir3   file1  file2

I need to take this :

/dir        file1
/dir1       file2
/dir2
/dir3

...and also each column sorted by time :wall:

This should work. It adjusts the directory column size based on the largest names seen in the list:

ls -pt | awk '
    /\/$/ {
        dcol[didx++] = $1;
        if( length( $1 ) > dmax )
            dmax = length( $1 );
        next;
    }
    {
        ccol[cidx++] = $1;
        next;
    }
    END {
        fmt = sprintf( "%%-%ds %%s\n", dmax );
        stop = didx > cidx ? didx : cidx;
        for( i = 0; i < stop; i++ )
            printf( fmt, dcol, ccol );
    }
'
1 Like

Very useful answer, thanks !
I try it but if a folder or file has space inside its name it doesn't give me the continue after the space..
for example if i have:

/dir 1  /file.exe
/dir 2  /dir3

I will get this answer:

/dir     /file.exe
/dir
/dir3

:wall: any ideas?
Also i have to use it inside c code.I should use system(); ??

Was ls specified in the question? Otherwise they might be expecting you to use C functions.

1 Like

It doesn't say exactly...
Maybe i should save the ls in a .txt (ls -l > a.txt)
and then sort the .txt but i don't know how to do that either :stuck_out_tongue:

I'd start with ls -F1

1 Like

I was thinking more that they might be expecting you to use man opendir ("3") and man readdir ("3").

1 Like

I think maybe this work

ls -t *.* > temp/files.txt
ls -pt */ >temp/dir.txt

and after somehow connect the two .txt's to be in columns ....
but i don't find a ls command to appear only the directories...
ls -pt */ gives me also the contents of the directories.
Any ideas??

---------- Post updated at 08:22 AM ---------- Previous update was at 08:21 AM ----------

It appears first the files and the the directories... but in columns ??? :confused:

---------- Post updated at 08:28 AM ---------- Previous update was at 08:22 AM ----------

hmmm i don't know to use these two ...
i'll try reading the manual, but i think i must use something easier that i have learned in class ....

a bit ugly and could be improved:

ls -p | grep '/$' >/tmp/d.$$
ls -p | grep '[^/]$'>/tmp/f.$$
paste /tmp/d.$$ tmp/f.$$
rm /tmp/d.$$ tmp/f.$$
1 Like

The -d option stops ls listing directory contents. You could also use find . -type d to list just directories.

1 Like

-UPDATE-

ls -t *.* > temp/files.txt
ls -1td */ > temp/dir.txt

i have the files' name listed in column at files.txt ans the directories' name listed also in column at dir.txt
Also the lists are time-sorted :smiley:
Now i need a way to connect the two .txt's contexts and appear in columns ....
Somehow with

cat

or

sort

?!?
Any ideas?? :wall:

look into my last post!

1 Like

YES !
thanks vgersh99, i didnt knew the command

paste

I think problem solved !!

mk dir temp
ls -t *.* > temp/f.txt
ls -1td */ > temp/d.txt
paste temp/f.txt temp/d.txt

:smiley:

Or a very small tweek to the original code I posted:

ls -pt | awk '
    /\/$/ {
        dcol[didx++] = $0;
        if( length( $0 ) > dmax )
            dmax = length( $0 );
        next;
    }
    {
        ccol[cidx++] = $0;
        next;
    }
    END {
        fmt = sprintf( "%%-%ds %%s\n", dmax );
        stop = didx > cidx ? didx : cidx;
        for( i = 0; i < stop; i++ )
            printf( fmt, dcol, ccol );
    }
'

If you're needing this from a compiled programme, I'd do the work in the programme.

1 Like

Wow, that code was impressive...
It's exactly what i wanted !
The code that i use with .txts has a little problems with columns...it's not lined up.. :stuck_out_tongue:
But this is perfect i think ...!
I don't know maybe it's a little too "specialized" for my project but thanks it's really educational..
Only a question, if i need to run this command inside a C programm under UNIX shell i should use the system(); and put inside the parenthesis the command??
Anyway thanks!:b:

I'd put it in a script and invoke the script using system(), much cleaner than trying to force the script into a C string.

#!/usr/bin/env ksh
awk '
.... awk programme goes here
' 
exit $?

If your file is named list_cols.ksh and is in a directory that is in the PATH, then your system() call should just be:

system( "list_cols.ksh" );

---------- Post updated at 21:34 ---------- Previous update was at 21:07 ----------

It's messy, and I'd have to think hard about approving it during a code walk through, but you could put it in a system() call directly if you don't want to maintain the additional script:

system(
        "ls -pt | awk '"
            "/\\/$/ {"
                "dcol[didx++] = $0;"
                "if( length( $0 ) > dmax )"
                    "dmax = length( $0 );"
                "next;"
            "}"
            "{"
                "ccol[cidx++] = $0;"
                        "next;"
            "}"
            "END {"
                "fmt = sprintf( \"%%-%ds %%s\\n\", dmax );"
                "stop = didx > cidx ? didx : cidx;"
                "for( i = 0; i < stop; i++ )"
                    "printf( fmt, dcol, ccol );"
            "}'");
1 Like