Como obter uma contagem de variáveis passadas para o awk [closed]

0

Eu estou tentando invocar o awk dentro de um script bash e passar alguns valores de variáveis do bash para ele. Existe alguma maneira de obter uma contagem dessas variáveis e imprimir todas as que são passadas para ele dentro do awk?

Não. de variáveis passadas para o awk seria dinâmico.

Abaixo do exemplo

#!/bin/bash
NAME="Dell"
SERIAL="12345"
echo "Hello" | awk -v a=$NAME -v b=$SERIAL '{ print a,b }'

Referenced, Working example, Irvur's answer in here

#!/bin/bash

function confirm_peers (){
  header_def=("${header_def[@]:-None}")
  read -r -p "Enter nodes from header[${header_def[*]}]: " -a header
  header=("${header[@]:-${header_def[@]}}") ;
  echo -e "\nInput Recorded - ${header[@]} \n"
}

createEncConfig()
{
 /usr/bin/awk -f - <<-'EOE' ${header[*]}  FS=":" $1
  BEGIN {
    count=1
    for (i = 1; i < ARGC - 2; ++i) {
    split(ARGV[i], ar, "=");
    print ar[2]
    }
print "\nCount=" ARGC -3
        }
EOE
}
confirm_peers
# Making array content adaptable to awk input
for x in ${!header[@]} ; do header[x]="a=${header[x]}"; done
createEncConfig $1

Referenced - Easiest so far , Kusalananda's answer

#!/bin/bash

function confirm_peers (){
  header_def=("${header_def[@]:-None}")
  read -r -p "Enter nodes from header[${header_def[*]}]: " -a header
  header=("${header[@]:-${header_def[@]}}") ;
  echo -e "\nInput Recorded - ${header[@]} \n"
}

createEncConfig()
{
/usr/bin/awk -v args="${header[*]}" -f - <<-'EOE' FS=":" $1
BEGIN {
  count=split(args,ar," ")
  for ( x in ar ) {
    print ar[x]
  }
print "\n" count
}
EOE
}
confirm_peers
createEncConfig $1

Saída: Basta passar qualquer arquivo fictício

$ bash /tmp/a.bsh /tmp/enc1.txt

Enter nodes from header[None]: a b c d

Input Recorded - a b c d

a
b
c
d

Count=4

Obrigado a todos ..

    
por Bharat 13.10.2018 / 03:06

5 respostas

2

Uma opção que posso pensar é reposicionar essas variáveis para que elas apareçam em ARGV . ARGC indicará quantos deles existem. Cuidado, isso torna as variáveis indisponíveis no bloco BEGIN . Você também precisa considerar os nomes de arquivo que você pode passar como parâmetros para awk , subtraindo o número de tais arquivos de ARGC

echo "Hello" | awk  '{ print a, b, ARGC - 1}' a=$NAME b=$SERIAL
DELL 12345 2
    
por 13.10.2018 / 03:15
1

Em seu comentário , parece que você tem uma matriz em bash que gostaria de passar para um programa awk na linha de comando.

Veja uma maneira fácil de fazer isso:

array=("my 1st item" "my 2nd item" "the last item")

(
    IFS=:

    awk -v var="${array[*]}" '
        BEGIN {
            array_len = split(var, array, ":")
            for (i = 1; i <= array_len; ++i)
                printf("Item #%d is \"%s\"\n", i, array[i])
        }'
)

Isso produziria

Item #1 is "my 1st item"
Item #2 is "my 2nd item"
Item #3 is "the last item"

Isso pega a matriz e a transforma em uma única sequência de itens : -delimited. Se algum dos elementos da matriz contiver : , escolha outro caractere para delimitar os itens na sequência. A expansão de ${array[*]} unirá os itens na matriz no primeiro caractere de $IFS , e é por isso que definimos essa variável antes de executar essa expansão. Esta string é passada para awk como a variável var .

No bloco BEGIN no programa awk , criamos a matriz array e também rastreamos o comprimento da matriz em array_len por meio da divisão de var on : . O loop é apenas para mostrar que conseguimos dividir a string com sucesso.

Definimos IFS e executamos nosso programa awk em um subshell para que o restante do script possa ser executado com uma variável IFS não modificada.

    
por 13.10.2018 / 17:10
0

Agora, como awk não fornece meios para obter sua própria linha de comando e as opções nela, isso é um pouco improvável e depende de componentes internos do linux como o sistema de arquivos proc , mas apenas para a diversão disso (YMMV):

awk -v"VAR1=sd" -va=b -vJ=onny '
BEGIN   {("tr \000\n \t </proc/$PPID/cmdline") | getline CMDLN
         n = split (CMDLN, ELM, "\t")
         for (i=1; i<=n; i++)   if (sub ("^-v", "", ELM[i]))    {split (ELM[i], T, "=")
                                                                 print "Option", T[1], "=", T[2]
                                                                 Options++
                                                                } 
        }
'
Option VAR1 = sd
Option a = b
Option J = onny

O "comando" que está sendo lido por getline será executado em um subshell, então chegaremos ao cmdline do PID pai e tr o <NUL> e <LF> caracteres a <TAB> s. Então, o CMDLN é split em seus elementos, em cada um dos quais um "-v" inicial é correspondido (e eliminado) para encontrar definições de variáveis. Esses são impressos e a contagem de opções é incrementada. Experimente.

    
por 13.10.2018 / 14:46
0

Você pode passar sua matriz para o awk diretamente com a string here.

awk -F'SEP' '{ print NF }' <<<"${header[*]}"

Em que SEP é o caractere com o qual seus elementos de matriz são delimitados.

Tset:

$ array=( 1, 2, 3, 7 )
$ awk -F',' '{ print NF }' <<<"${array[*]}"
4

E $1 será o valor do seu primeiro elemento, $2 segundo e etc.

    
por 13.10.2018 / 18:06
0

Como você tem uma matriz bash e o bash sabe quantos elementos estão na matriz, simplesmente informe diretamente o awk:

$ array=("my 1st item" "my 2nd item" "the last item")
$ awk -v var="${array[*]}" -v nargs=${#array[@]} '
  BEGIN {
    print nargs;
  }
'
3
    
por 14.10.2018 / 02:43

Tags