LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Parsing columns in bash (https://www.linuxquestions.org/questions/linux-newbie-8/parsing-columns-in-bash-758169/)

seb357 09-28-2009 12:39 AM

Parsing columns in bash
 
Hi,

as a result of a find command, i have

852065 72: /bin/gunzip
852065 72: /bin/gzip
852065 72: /bin/zcat


(the first column is inode number and the second is size if you're curious)

I want to be able to format it in a way such that:
852065 72:
/bin/gunzip
/bin/gzip
/bin/zcat

I know I can get the bottom half using awk- but I can't figure out how to extract the first set of numbers and get them to appear only once

any help?

Thanks!

lutusp 09-28-2009 12:52 AM

Quote:

Originally Posted by seb357 (Post 3699104)
Hi,

as a result of a find command, i have

852065 72: /bin/gunzip
852065 72: /bin/gzip
852065 72: /bin/zcat


(the first column is inode number and the second is size if you're curious)

I want to be able to format it in a way such that:
852065 72:
/bin/gunzip
/bin/gzip
/bin/zcat

I know I can get the bottom half using awk- but I can't figure out how to extract the first set of numbers and get them to appear only once

any help?

Thanks!

You aren't explaining it very well. Do the first two numbers ever change? Do you have a longer example from the data source? Without that I am only guessing about what might work.

Also, do you really think you can list multiple files, all with the same inode number? That's not how inode numbers work.

Pretend that the information matters to the solution (because it does). Explain the problem properly -- otherwise there is no chance to solve it.

seb357 09-28-2009 12:55 AM

Quote:

Originally Posted by lutusp (Post 3699109)
You aren't explaining it very well. Do the first two numbers ever change? Do you have a longer example from the data source? Without that I am only guessing about what might work.

Also, do you really think you can list multiple files, all with the same inode number? That's not how inode numbers work.

Pretend that the information matters to the solution (because it does). Explain the problem properly -- otherwise there is no chance to solve it.


The first numbers change depending on the directory:

for example, if i execute

find /bin ! -type d -links +2 -ls 2>/dev/null | sort -g | awk '{ print $1, $2":", $11 }'

then the result above appears

My issue is mainly with formatting, i'm just new to using bash

lutusp 09-28-2009 01:02 AM

Quote:

Originally Posted by seb357 (Post 3699114)
The first numbers change depending on the directory:

for example, if i execute

find /bin ! -type d -links +2 -ls 2>/dev/null | sort -g | awk '{ print $1, $2":", $11 }'

then the result above appears

My issue is mainly with formatting, i'm just new to using bash

Don't post your idea for a solution, instead describe the problem to be solved. Be detailed and specific.

Tinkster 09-28-2009 01:54 AM

Quote:

Originally Posted by seb357 (Post 3699104)
Hi,

as a result of a find command, i have

852065 72: /bin/gunzip
852065 72: /bin/gzip
852065 72: /bin/zcat


(the first column is inode number and the second is size if you're curious)

I want to be able to format it in a way such that:
852065 72:
/bin/gunzip
/bin/gzip
/bin/zcat

I know I can get the bottom half using awk- but I can't figure out how to extract the first set of numbers and get them to appear only once

any help?

Thanks!

As others have said, it's not very clear ... but
does the snippet of awk do what you want?
save to script.awk, rund like
find .... | awk -f script.awk
Code:

BEGIN{
        FS=":"
        hold=""
}
{
        if ( hold != $1 ){print $1}
        if( NR > 2 && hold == $1 ){
                print $2
        } else {
                print $2
                hold = $1
        }
}



Cheers,
Tink

catkin 09-28-2009 02:22 AM

Quote:

Originally Posted by lutusp (Post 3699121)
Don't post your idea for a solution, instead describe the problem to be solved. Be detailed and specific.

Don't we usually like people to post both their problem and their attempt at a solution? I fully agree that questions simply asking how to make a solution work can be unproductive because the solution may be sub-optimal, even unworkable. In this case the solution attempt does clarify that the problem really is about files with multiple hard links -- and that's useful because it is increasingly unusual.

seb357 09-28-2009 08:21 AM

Quote:

Originally Posted by catkin (Post 3699163)
Don't we usually like people to post both their problem and their attempt at a solution? I fully agree that questions simply asking how to make a solution work can be unproductive because the solution may be sub-optimal, even unworkable. In this case the solution attempt does clarify that the problem really is about files with multiple hard links -- and that's useful because it is increasingly unusual.

I'm trying to be as general as possible

say you have a long listing:

ls -l

-rw-r--r-- 2 seb357 faculty 1215 Mar 25 2009 banana
-rw-r--r-- 1 seb357 faculty 443 Sep 27 18:06 chkopts.bash
-rw------- 1 seb357 faculty 358 Mar 31 2008 dead.letter
drwxr-sr-x 3 seb357 faculty 4096 Apr 13 16:28 gasudoku


I want to be able to capture a single cell from that table, so i could do something like making a variable named user = seb357

catkin 09-28-2009 11:58 AM

Quote:

Originally Posted by seb357 (Post 3699377)
I'm trying to be as general as possible

If you really want to be as generic as possible (= portable to various *n*x versions) then you don't want to use ls to generate a list of files or ls -l to get information about them for the reasons explained here.

If "as general as possible" is on a version of *n*x that produces ls -l output in the same format as on your current version and only operates on files with names that ls can display then
Code:

#!/bin/bash
shopt -s extglob
IFS='
'
for line in $(/bin/ls -l)
do
    unset IFS  # Equivalent to setting it back to the default
    array=( $line )
    [[ "${array[0]}" == 'total' ]] && continue  # Skip headng
    perms="${array[0]}"
    link_count="${array[1]}"
    user="${array[2]}"
    filename="${line##*:*([0-9]) }"
    echo "\$perms is '$perms'"
    echo "\$link_count is '$link_count'"
    echo "\$user is '$user'"
    echo "\$filename is '$filename'"
done


H_TeXMeX_H 09-28-2009 02:37 PM

For example 1:

The simplest way I can think of to get the output above from the input above is:

Code:

find ... | awk '{ if (NR == 1) printf("%s %s\n%s\n", $1, $2, $3); else print $3 }'
That's of course assuming that the first two columns are always the same.

For example 2:

Code:

bash-3.1$ var=$(ls -l | cut -d' ' -f4 | head -n1)
bash-3.1$ echo $var
faculty


seb357 09-28-2009 02:40 PM

haha, as generic as possible for my two systems :)

Thank you a lot catkin, that's exactly what i needed


All times are GMT -5. The time now is 05:47 AM.