Como construir uma longa cadeia de comandos?

3

Eu tenho uma seqüência de comandos a serem usados junto com muitos canais, algo assim:

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

Isso basicamente filtra o log do Apache e imprime três cols de informação. Primeiro col é o endereço IP, segundo é hora, terceiro é uma string. A saída pode ser classificada com base em qualquer coluna, portanto, preciso usar '-m' com classificação para o campo de hora. Ordem de classificação também pode ser revertida.

Eu quero que uma string armazene os argumentos para classificar e deixe as sequências combinadas serem executadas. Algo parecido com isto:

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

onde

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

Sou capaz de construir essas cadeias de caracteres; quando eu faço eco, parece bem. Problema é, como executá-lo? Eu recebo alguns erros como:

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

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

if [[ $REVERSE -eq 1 ]]
then
    SORT_REV="-r"
else
    SORT_REV=
fi

final_cmd="awk '{ if (\ ~ \"isad\") {print \, \, \"SE\"} else {print \, \, \"ANT\"} }' $LOG_FILE '|' grep -v '127.0.0.1' '|' tr '[' '
awk '{ if ($8 ~ "isad") {print $2, $5, "SE"} else {print $2, $5, "ANT"} }' "/var/log/apache2/other_vhosts_access.log" | grep -v '127.0.0.1' | tr '[' '
$AWK_CMD | $SORT_CMD $SORT_KEY $SORT_REV
' | tr [:lower:] [:upper:] | sort -t' ' -s -k3
' '|' tr [:lower:] [:upper:] '|' $SORT_CMD $SORT_KEY $SORT_REV" echo $final_cmd echo "Running ..." $final_cmd

Por favor, ignore se 'sort' não classificar corretamente, isso pode ser corrigido. Eu gostaria de saber como posso construir a string de comando final em etapas. As formas que tentei executar este comando no script são:

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

Editar: o script que estou tentando usar

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

2 respostas

3

As diferentes partes podem ser colocadas nas funções do shell:

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 '127.0.0.1' | tr '[' '
dosort() {
    rev=""
    if [ "$2" == "reverse" ]
    then
        rev='-r'
    fi
    sort -t' ' -s -k$1 $rev
}
' | toupper | dosort

você pode tornar as coisas mais fáceis:

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 '127.0.0.1' | tr '[' '
dosort() {
    rev=""
    if [ "$2" == "reverse" ]
    then
        rev='-r'
    fi
    sort -t' ' -s -k$1 $rev
}
' | toupper | dosort

Quando sua linha de comando está começando a ficar muito longa, escrevê-la em um script e dividi-la em partes (com funções) geralmente é muito útil.

    
por 18.02.2011 / 13:48
1

Quando você executa awk '{ ... }' em um prompt do shell ou a partir de um shell script, o shell analisa as aspas e passa o argumento para awk sem as aspas. O que acontece é que você de alguma forma o executa com as aspas no parâmetro.

Editar: com sua atualização para a pergunta, o que você precisa é de sh -c "$final_cmd" .

    
por 18.02.2011 / 13:26