Procura por padrão, depois adiciona texto na terceira linha em branco

2

Procurando por padrão e depois contando cada linha em branco após o padrão até que a terceira linha em branco seja encontrada; então eu quero colocar uma vírgula e um ponto e vírgula nessa linha em branco. Pode haver muitos dados entre as linhas em branco ou apenas uma linha de texto entre as linhas em branco.

GROUP DIRECTORY CATEGORIES
datadata

Grouping Cat
datadata

datadata
this is the 3rd blank line

Eu tentei o seguinte sem sucesso. Alguma sugestão?

sed '/GROUP DIRECTORY CATEGORIES/,/^$/^$/^$/,;/' file1>file2
sed '/GROUP DIRECTORY CATEGORIES/$/$/$/,;/' file1>file2
sed '/GROUP DIRECTORY CATEGORIES/{$;$;$/./,;/1;}' file1>file2
    
por 985ranch 02.09.2016 / 01:35

3 respostas

3

Enquanto sed pode ser usado para isso, qualquer coisa que envolva contagem é geralmente mais fácil com awk .

Vamos considerar este arquivo de teste:

$ cat file1
GROUP DIRECTORY CATEGORIES
datadata

Grouping Cat
datadata

datadata

Above is 3rd blank line

Para adicionar um ,; à terceira linha em branco após GROUP DIRECTORY CATEGORIES :

$ awk '/GROUP DIRECTORY CATEGORIES/{f=1}  f && /^$/ {f++; if (f==4) $0=",;"} 1' file1
GROUP DIRECTORY CATEGORIES
datadata

Grouping Cat
datadata

datadata
,;
Above is 3rd blank line

Como funciona:

  • /GROUP DIRECTORY CATEGORIES/{f=1}

    Sempre que for encontrada uma linha que corresponda à regex GROUP DIRECTORY CATEGORIES , a variável f será definida como 1.

  • f && /^$/ {f++; if (f==4) $0=",;"}

    Se f for diferente de zero e a linha atual estiver em branco, /^$/ , então incremente f em um. Se f for 4, substitua a linha em branco atual por ,; .

  • 1

    1 é a abreviatura enigmática do awk para imprimir na linha.

por 02.09.2016 / 01:57
0

Fundamentalmente, sua abordagem falha porque sua expressão está apenas lendo uma única linha em seu espaço de padrão a cada vez - portanto, ela nunca pode corresponder a várias linhas em branco (mesmo se você pudesse construir um regex apropriado).

No entanto, é possível ler várias linhas no espaço padrão usando o comando N em um loop. Com a possível exceção do modificador de múltiplas linhas do GNU sed, novas linhas são representadas no espaço de padrões de múltiplas linhas como \n seqüências - então, para testar linhas em branco, você precisará usar \n\n em vez de ^$ . Então, por exemplo:

sed -E '
  /GROUP DIRECTORY CATEGORIES/ {
  :a                            # label the start of a loop
  $!N                            # if not at the end of file, read & append the next line
  s/((\n\n.*){2})\n\n/\n,;\n/ # match and capture 2 instances of successive newlines, 
                                # followed by a 3rd; if found, replace the 3rd by \n,;\n 
  t                             # branch out of the loop on successful replacement
  ba                            # else branch back to label 'a'
  }' file1

No GNU sed, a sequência t;ba pode ser substituída por Ta .

    
por 02.09.2016 / 05:32
0

Esse tipo de requisito de endereçamento complexo é onde ex (ou vi ) realmente brilha.

ex é uma ferramenta especificada por POSIX que é a predecessora de vi (o "editor visual".) É notável que todos os comandos ex -style permanecem utilizáveis em vi bem como no Vim.

Em vi ou Vim, supondo que você queira a primeira instância de /pattern/ do início do documento, faça isso da seguinte maneira:

  • Abra o arquivo na linha de comando digitando vi file.txt e pressionando <Enter>

  • Digite o seguinte, incluindo os dois pontos principais. Em seguida, pressione <Enter> .

    :0/GROUP DIRECTORY CATEGORIES//^$//^$//^$/s/^/,;/
    
  • Salve as alterações digitando :x e pressionando <Enter> .

No comando acima, tudo até o minúsculo s é apenas um endereço . O comando s deve ser bastante óbvio.

O endereço significa, "Desde o início do arquivo (linha '0'), a primeira instância para a frente de 'CATEGORIAS DE DIRETÓRIO DE GRUPO' e, a partir daí, a primeira instância para a frente de uma linha em branco. uma linha em branco, depois a próxima, depois execute o comando substituto. "

Existem muitas outras maneiras de dividir isso; não precisa ser um forro.

Você também pode realizar essa edição com os seguintes comandos ex :

0/GROUP DIRECTORY CATEGORIES/
/^$/
//
//
s//,;/
x
    
por 03.09.2016 / 01:25