Dividir arquivo por padrão mantendo apenas as partes que contêm um segundo padrão

3

Eu encontrei o seguinte script awk em uma resposta anterior para dividir arquivos grandes em partes menores com base em um padrão (substituindo "header-line" por um padrão diferente). No entanto, tenho a necessidade de levá-lo ainda mais longe, pois pode haver milhões de peças criadas, mas se eu puder filtrar cada uma novamente, ela terá o que preciso.

awk '
    /header-line/ {++part}
    {print >sprintf("part-%03d.txt", part)}
'

É possível interrogar cada "parte" antes ou depois de ser escrita para verificar se existe um determinado padrão na peça e apenas escrever essa parte em uma correspondência para o padrão adicional.

Como exemplo, o critério inicial seria "ID:" (a linha de cabeçalho acima). Eu então quero pesquisar cada "parte" criada para um nome de método específico; chame-o de "searchForThisMethod" como a string a ser pesquisada, que pode estar em vários locais da peça.

Exemplo de entrada:

ID: 1
bb
bb
bb
bb
secondaryCheck
ID: 2
b
b
b
b
b
b
b
b
ID: 3
h
h
h
h
h
secondaryCheck
g
g
g
g
    
por user7972 27.06.2016 / 20:06

1 resposta

1

Você pode dividir o arquivo, em seguida, executar grep -q some_method em cada parte e excluí-la, se falso , por exemplo,

for file in part-*.txt; do
grep -q some_method "$file"
  if [ $? -ne 0 ]
    then
      rm "$file"
  fi
done

ou
use duas passagens - removendo da entrada as "partes" que contêm some_method e depois dividindo o resultado, por ex. usando sed para a primeira passagem e seu awk para a segunda passagem:

sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{print > sprintf("part-%03d.txt", part)}'

sed copia a 1 ª linha sobre o buffer h old e d elimina, em seguida, acrescenta cada linha que não corresponde a ID ao buffer H old, exclui se não for a última linha e e x altera os buffers nas linhas que correspondem a ID excluindo o espaço padrão se ele não contiver some_method . O resultado é então canalizado para awk . Se você está recebendo too many open files erro, você terá que close() dos arquivos:

sed -e '1{h;d;}' -e '/ID/!{H;$!d;}' -e 'x;/some_method/!d' infile | \
awk '/ID/{++part}{close(fn);fn=sprintf("part-%03d.txt", part);print >> fn}'

ou, se você estiver em gnu / anything, poderá usar csplit em vez de awk :

sed '1{h;d};/ID/!{H;$!d};x;/some_method/!d' infile | \
csplit -f 'part-' -b '%03d.txt' -sz - /ID/ '{*}'
    
por 28.06.2016 / 01:29