Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWK - passing generated string as code for awk from command line

Tags:

bash

unix

ksh

awk

I am trying to dynamically print selected fields of a file using awk.

Basically, the question is why this one works:

awk -F';' '{print $3 ";" $4 ";" }' file

but this does not:

awk -F';' '{print '`echo '$3 ";" $4 ";"'`' }' file

My final goal is to encapsulate the above in one command so that I would be able to do

my_cmd ';' 3 6 7 8 file(s)

which should display the fields #3,6,7,8 delimited by ; from file(s).

Editing my post: Found out myself that my problem was echo was inserting of course a new line caracter which was causing issue for awk :o) \c did the trick, also some \" escaping had to do (see below).

awk -F';' '{print '"`echo '$3 \";\" $4 \";\"\c'`"' }' file(s)

Now I'm only left to change it with command which will generate dinamically a string like $2 ";' $5 ";' $6 ";' $9 ";" (number and fields should be the intput) etc. which should go between '{print ' and ' }'

Thanks to cbuckley I found out my one line command: (Issue solved).

cut -d"$1" -f `shift; echo $* | sed 's/[^ 0-9]\{1,\}.*$//;s/[ ]$//;s/[ ]\{1,\}/,/g'` `shift; printf "%s\n" $(echo $*) | grep -v '^[0-9]$'`

here $* are the input parameters and if above would be as an alias or a function in your .rc file named say filterc then the synopsys would be:

filterc delimiter column1 [column2 [column3...]] file1 [file2 [file3...]]  

where:

delimiter - one char only

column1..n - a number representing the column

file1..n - files to be filtered, assumption here that files will not have names from numbers only and that all are of same format.

like image 528
vadimbog Avatar asked Mar 27 '26 05:03

vadimbog


2 Answers

Your command sounds very similar to cut:

cut -d ';' -f 1,3 <<EOT
one;two;three
foo;bar;quux
EOT

one;three
foo;quux

cut -d '-' -f 2,4 <<EOT
one-two-three-four
five-six-seven-eight
EOT

two-four
six-eight
like image 111
cmbuckley Avatar answered Mar 28 '26 22:03

cmbuckley


Is this what you are after?

#!/bin/bash

get_columns()
{
    local fs=$1; shift
    local _awk=
    local column

    for column; do
        _awk="${_awk}\$${column},"
    done
    awk -F"$fs" -v OFS="$fs" "{ print ${_awk%,} }"
}

get_columns ';' 1 3 <<EOT
one;two;three
foo;bar;quux
EOT

get_columns '-' 2 4 <<EOT
one-two-three-four
five-six-seven-eight
EOT

-

$ ./t.sh
one;three
foo;quux
two-four
six-eight
like image 37
Adrian Frühwirth Avatar answered Mar 28 '26 22:03

Adrian Frühwirth