Coloca dados grandes de offset de bytes heterogêneos em matrizes pelo AWK

1

Suponha que os dados consistam em deslocamento de byte que não é fixo, ou seja, a distância de dois cabeçalhos de arquivo subseqüentes varia. O ponto deste segmento é percorrer cada tamanho de eventos separadamente em matrizes.

Exemplo de dados

fafafafa
00005e58
da1e5afe
00000000
*
fafafafa
00005e58
da1e5afe
00000000
*
00000001
ffffffff
555eea72
00000000
*
00000004
fafafafa
01da1300
*
00000004
02991c00
fafafafa
01da1300
fafafafa
01da1300
fafafafa
01da1300

em que o delimitador de campo é fafafafa .

Minha proposta

#!/bin/bash
# http://stackoverflow.com/a/10383546/54964

# http://unix.stackexchange.com/a/209789/16920
myarr = ($( cat 25.6.2015_test.txt | awk -F 'fafafafa' '$1~/^[a-z0-9*]+$/ {print $1}') )

# http://stackoverflow.com/a/15105237/54964
# Now access elements of an array (change "1" to whatever you want)
echo ${myarr[1]}

# Or loop through every element in the array
for i in "${myarr[@]}"
do
   :
  echo $i
done

Script executado como um todo

Saída

awk2array.sh: line 5: syntax error near unexpected token '('
awk2array.sh: line 5: 'myarr = ($( cat 25.6.2015_test.txt | awk -F 'fafafafa' '$1~/^[a-z0-9*]+$/ {print $1}') ) '

que eu não entendo, desde colchetes. Eu gostaria de obter a saída em uma matriz ou armazenar cada evento em um arquivo chamado aritmeticamente (0.txt, 1.text, ..., n.txt). Eu agora descrevo alguns dos comandos separadamente e algumas partes dos códigos sobre os quais eu sou incerto.

O comando

AWK é executado separadamente

O comando AWK quando executado separadamente omite o delimitador de campo, fornecendo

00005e58
da1e5afe
00000000
*
00005e58
da1e5afe
00000000
*
00000001
ffffffff
555eea72
00000000
*
00000004
01da1300
*
00000004
02991c00
01da1300
01da1300
01da1300

A saída desejada é ter todos os dados no array em que o separador de campo é fafafafa , de forma que fafafafa seja incluído na célula, por exemplo

Value of first cell in array
----------------------------
fafafafa
00005e58
da1e5afe
00000000
*

Value of second cell
--------------------
fafafafa
00005e58
da1e5afe
00000000
*
00000001
ffffffff
555eea72
00000000
*
00000004

3rd cell
--------
01da1300
*
00000004
02991c00

4th cell
--------
fafafafa
01da1300

5th cell
--------
fafafafa
01da1300

6th cell
--------
fafafafa
01da1300

Como você pode armazenar dados grandes no array N pelo AWK? Você também pode armazenar cada evento em um arquivo depois de lê-lo sem começar a ler o arquivo novamente e continuar a partir do ponto a esquerda.

    
por Léo Léopold Hertz 준영 25.06.2015 / 08:35

3 respostas

3

Problema

Tantas coisas erradas aqui

#!/bin/bash

myarr = (

tem um espaço entre ele, significando que nada é atribuído se ele for executado.

cat 25.6.2015_test.txt | awk

Awk pode abrir seus próprios arquivos sem necessidade de gato

-F 'fafafafa' '$1~/^[a-z0-9*]+$/

-F é o separador de campo não registrado, então tudo isso é remover o texto fafafafa , ele ainda está lendo cada linha como um registro, então sua próxima condição é totalmente inútil.

myarr = ($( cat 25.6.2015_test.txt | awk -F 'fafafafa' '$1~/^[a-z0-9*]+$/ {print $1}') )

Isso imprimirá várias linhas, que serão elementos separados na matriz, já que estão divididas em novas linhas e não têm visibilidade do que é um registro no awk (se você tivesse realmente dividido em registros em vez de campos).

echo ${myarr[1]}
echo $i

Cite isso, a menos que você queira ver todos os arquivos em seu diretório sempre que fizer eco (devido ao * nos registros)

 :

Por quê?

Solução

# Create an array
myarr=()
# Save the number of different blocks to be saved, notice the 
# '-vRS' which sets the field separator
blocks=$(awk -vRS='fafafafa' '$1~/^[a-z0-9*]+$/{x++}END{print x}' file)

# While the the counter is less than the number of blocks.
while [[ $x -le $blocks ]] ;do
    # Increase the counter
    ((x++))
    # Add the value for that block to the array, notice the quotes around
    # '$()', they are important in keeping all the block as one array 
    # element. The awk also increments its own counter for each 
    # occurrence of 'fafafafa' and your condition for '$1'. When both
    # counters match the block is saved to the array.
    myarr+=("$(awk -vRS='fafafafa' -vN="$x" '$1~/^[a-z0-9*]+$/{x++}
                                             x==N{print RS$0}' test)")

done
    
por 25.06.2015 / 10:17
3
while read -d '&' -r data
do 
    myarr[${#myarr[@]}]="$data" 
done < <(sed '1! s/fafafafa/\&&/' 25.6.2015_test.txt) 

colocará todos os seus dados do arquivo 25.6.2015_test.txt no array myarr separado por fafafafa completamente com ele. sed é usado para colocar o caractere delimitador & (você pode usar qualquer um que não seja esperado no texto) antes de fafafafa , exceto a primeira linha (no caso oposto, recebemos o primeiro membro vazio da matriz). read coloca a parte do texto separada por & na variável intermediária data . ${#myarr[@]} produz o número de elementos na matriz myarr . Como a numeração começa em 0 , podemos receber o índice do próximo elemento da matriz:

  • matriz vazia, número de elementos é 0, então o primeiro elemento tem índice == 0
  • A matriz
  • tem 1 elemento com índice 0, portanto, o número de elementos é 1, próximo índice == 1
  • O array
  • tem 2 elementos com índices 0,1, portanto, o número de elementos é 2, próximo índice == 2
por 25.06.2015 / 10:15
1

A linha

myarr = ($( cat 25.6.2015_test.txt | awk -F 'fafafafa' '$1~/^[a-z0-9*]+$/ {print $1}') 

está errado. Use a linha abaixo:

myarr=$(awk -F 'fafafafa' '$1~/^[a-z0-9*]+$/ {print $1}' 25.6.2015_test.txt) 

E você deve usar " :

echo "${myarr[1]}"

e

echo "$i"

E você poderia usar este comando awk

  • com fafafafa :

    awk '{if ($1 ~ /^fafafafa$/) {line+=1; print ""; print "cell "line;print "--------"; print $1} else {print $1}}' 25.6.2015_test.txt
    
  • sem fafafafa

    awk '{if ($1 ~ /^fafafafa$/) {line+=1; print ""; print "cell "line;print "--------";} else {print $1}}' 25.6.2015_test.txt
    

Exemplo de saída sem fafafafa

cell 1
--------
00005e58
da1e5afe
00000000
*

cell 2
--------
00005e58
da1e5afe
00000000
*
00000001
ffffffff
555eea72
00000000
*
00000004

cell 3
--------
01da1300
*
00000004
02991c00

cell 4
--------
01da1300

cell 5
--------
01da1300

cell 6
--------
01da1300
    
por 25.06.2015 / 09:19