Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've a sequence of commands to be used along with lot of pipings, something like this:

awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3

This basically filters the Apache log and prints three cols of info. First col is IP address, second is time, third is a string. The output could be sorted based on any column so, I need to use '-m' with sort for the time field. Sorting order could also be reversed.

I want a string to store the arguments to sort, and let the combined strings get executed. Something like this:



SORT_CMD="sort -t' '"
SORT_KEY="-k$1"      # $1 from cmd line arg
SORT_REV="$2"        # Either -r or blank

Am able to build such strings; when I echo it, it looks fine. Problem is, how to execute it? I get some errors like:

awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '' | tr '[' '\0' | tr [:lower:] [:upper:] | sort -t' ' -s -k3
Running ...
awk: '{
awk: ^ invalid char ''' in expression

Please ignore if 'sort' doesn't sort properly, that can be fixed. I wish to know how I can build the final command string in steps. The ways I tried to execute this command in the script is by:


Edit: The script that I'm trying to use

KEY=$1      # Values {1, 2, 3}
REVERSE=$2  # Values {0, 1} 

SORT_CMD="sort -t' ' -s"
if [[ $KEY -eq 2 ]]
    SORT_KEY="-m -k2"

if [[ $REVERSE -eq 1 ]]

final_cmd="awk '{ if (\$8 ~ \"isad\") {print \$2, \$5, \"SE\"} else {print \$2, \$5, \"ANT\"} }' $LOG_FILE '|' grep -v '' '|' tr '[' '\0' '|' tr [:lower:] [:upper:] '|' $SORT_CMD $SORT_KEY $SORT_REV"

echo $final_cmd
echo "Running ..."
share|improve this question

2 Answers 2

up vote 3 down vote accepted

The different parts can be put in shell functions :

awkfilter() {
    awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' $1

toupper() {
    tr [:lower:] [:upper:]

dosort() {
    sort -t' ' -s -k3

awkfilter "/var/log/apache2/other_vhosts_access.log" | grep -v '' | tr '[' '\0' | toupper | dosort

then you could make things optionnal more easily :

dosort() {
    if [ "$2" == "reverse" ]
    sort -t' ' -s -k$1 $rev

When your command-line is starting to be really long, writing it in a script and breaking it in parts (with functions) is usually really helpfull.

share|improve this answer
Thanks, Fussy! I too was trying to achieve the same, however, with string concatenation. But I think you gave me a better option. :) –  Barun Feb 18 '11 at 13:02

When you run awk '{ ... }' on a shell prompt or from a shell script, shell parses the quotes and passes the argument to awk w/o the quotes. What happens is that you somehow run it with the quotes in parameter.

Edit: with your update to question, what you need is sh -c "$final_cmd".

share|improve this answer
Like alex says, somehow the quote stays on execution. Can you (Barun) post the contents of $final_cmd and how you got it set? –  asoundmove Feb 18 '11 at 12:31
Sure. I'm appending the script to my original post. –  Barun Feb 18 '11 at 12:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.