Encontre o padrão e remova-o de todos os arquivos [fechados]

1

Por favor, ajude-me a resolver o problema seguinte. Remova todos os pares de caracteres \ n do Test_Macro em todos os arquivos. Por favor, veja o exemplo abaixo:

Fil1.txt

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

dir1 / arquivo2.txt

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

Resultado esperado:

Arquivo1.txt

Test_Macro(abc, def, " string1 string2 test string",
   "test string2 ");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

dir1 / arquivo2.txt

Test_Macro(abc, def, " string1 string2  test string",
   "test string2 ",
    123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

Qualquer ajuda ou sugestão é muito apreciada. Estou planejando escrever algum roteiro. Porque eu tenho muitos tipos diferentes de arquivos e muitas dessas macros. Obrigado antecipadamente!

Os argumentos para Test_Macro podem ter chamadas aninhadas para outras macros e podem ter qualquer caractere dentro de strings.

    
por mehtame026 27.10.2016 / 02:54

3 respostas

0

Arquivo1:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*//;p;};d' abc.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");

Arquivo2:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*//;p;};d' abc2.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
Test_Macro(asdsadas, "test String1");

ps, a maneira mais fácil de remover todas as quebras de linha é

echo -e "line \n break" | tr "\n" " "

sem quebras de linha;

$ sed ':a;N;$!ba;s/[^;]\n[ ]*/ /g;' abc2.txt  | grep Test_Macro
Test_Macro(abc, def, "\n string1 string2 \n test string" "test string2 \n" 123456);
Test_Macro(asdsadas, "test String1");

sem "\ n", mas com quebras de linha ... lol

$ sed '/Test_Macro/{N;$!N;s/[ ]*\n//g;s/.*\(Test_Macro[^)]*);\).*//;p;};d' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
Test_Macro(asdsadas, "test String1");

apenas removendo a string "\ n" (e o espaço à direita);

$ sed ':a;N;$!ba;s/\n[ ]*//g;' abc2.txt
Test_Macro(abc, def, "string1 string2 test string",
       "test string2 ",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

mais uma vez (espero que da última vez) ... removendo string "\ n" quando na função Test_Macro, mas não fora, e não removendo quebras de linha;

$ sed '{N;/Test_Ma/{s/[ ]*\n//g;};s/\(Test_Macro[^)]*);\)//};' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...

atualização;

$ sed '{:a;N;/Test_Ma/{s/[ ]*\n//g;};ta};' abc2.txt 
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
        123456);
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...
    
por 27.10.2016 / 03:24
2

Existe uma frase que deve ser lembrada, "expressões regulares não podem contar".

Isso é importante neste caso, porque muitas ferramentas simples do Unix são baseadas em expressões regulares. A contagem aqui está contando os parênteses de abertura e fechamento ('parênteses arredondados') que podem ser usados dentro dos argumentos para Test_Macro.

Se as chamadas para Test_Macro nunca tiverem parênteses aninhados, então existe um truque fácil. Primeiro, altere cada caractere ) para uma nova linha e vice-versa. Em seguida, exclua todas as linhas que não contenham o Test_Macro e remova tudo para o Test_Macro. Neste ponto, uma parte do File2.txt processado seria semelhante a este

Test_Macro(abc, def, " string1 string2 test string",)   "test string2 ",)    123456

Então, agora precisamos converter o ) de volta. Neste ponto, você tem algumas opções. Eu prefiro usar sed para se livrar dos espaços extras ao mesmo tempo. Também precisamos adicionar de volta o ) e talvez o ;

Juntando isso, temos

find . -type f | while read -r fn
do
   < "$fn" tr ')\n' '\n)' | sed -n 's/.*Test_Macro(/Test_Macro(/p' | \
     sed 's/) */ /g;s/$/);/'
done

Se houver a possibilidade de que os argumentos para o Test_Macro incluam parênteses aninhados, será necessário exibir armas significativamente maiores, já que você precisará analisar a entrada em vez de apenas padronizar a correspondência. (Em teoria, se você pode restringir o nível de aninhamento, então você pode combinar com o padrão, mas na prática isso fica muito complicado muito rapidamente e você deve descontar essa abordagem). Existem estruturas parser para linguagens como python, ou você pode construir ferramentas sobre ferramentas como lex.

    
por 27.10.2016 / 07:11
1

Editar: Esta resposta foi preparada antes da questão ser revisada. A forma original da pergunta incluía:

When I tried to find some pattern using "grep", it only prints first line. But I want till end of the bracket.

Expressões regulares não podem contar, mas Sed pode fazer loop.

Aqui está um snippet Sed que será coletado de qualquer linha que contenha Test_Macro para a linha com o paren de fechamento apropriado, mesmo se houver parênteses aninhados:

#n
/Test_Macro/{
  p;
  :rep
  s/([^()]*)//;
  trep
  /^[^(]*$/d;
  h;
  n;
  p;
  x;
  G;
  brep
}

Convertido para um one-liner, é assim:

sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}'

Entrada e saída são assim:

$ cat temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...
$ sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}' temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");
$ 
    
por 28.10.2016 / 02:52