1

I have written a shell script to get any column. The script is:

#!/bin/sh
awk '{print $c}' c=${1:-1}

So that i can call it as

ls -l | column 2

But how do i implement it for multiple columns? Say, it i want something like :

ls -l | column 2 3

3 Answers 3

6

In this case, I wouldn't use awk at all:

columns() { tr -s '[:blank:]' ' ' | cut -d ' ' -f "$@"; }

This uses tr to squeeze all sequences of whitespace to a single space, then cut to extract the fields you're interested in.

ls -l | columns 1,5,9-

Note, you shouldn't parse the output of ls.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 for the right solution. I'd probably use tr -s '[:blank:]' '\t' just so you don't need to specify -d ' ' in the cut args but nbd.
3
awk -v c="3,5" '
    BEGIN{ split(c,a,/[^[:digit:]]+/) }
    { for(i=1;i in a;i++) printf "%s%s", (i==1?"":OFS), $(a[i]); print "" }
'

Use any non-digit(s) you like as the column number separator (e.g. comma or space).

Comments

2
ls -l | nawk -v r="3,5" 'BEGIN{split(r,a,",")}{for(i in a)printf $a[i]" ";print "\n"}'

Now you can simply change your r variable in shell script and pass it on. or you can configure it in your shell script and use r=$your_list_var

What ever fields numbers are present in $your_list_var will be printed by awk command. The example above print 3rd and 5th fields of ls -l output.

2 Comments

+1, but put the split in the BEGIN block so you don't have to do it for every line.
Will fail cryptically when the input file contains printf formatting characters and won't necessarily output fields in the input order, nor in the order of the argument. It will also add a space to the end of each line and a spurious newline between each output line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.