Por favor me ajude a resolver o seguinte problema. Remova todos os pares de caracteres \
n
de 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 tenho muitos tipos diferentes de arquivos e muitas dessas macros. Desde já, obrigado!
Os argumentos para Test_Macro podem ter chamadas aninhadas para outras macros e podem ter quaisquer caracteres dentro de strings.
Responder1
Há uma frase que deve ser lembrada: “expressões regulares não contam”.
Isso é importante neste caso porque muitas ferramentas Unix 'simples' são baseadas em expressões regulares. A contagem aqui é a contagem dos parênteses de abertura e fechamento ('colchetes') que podem ser usados dentro dos argumentos para Test_Macro.
Se as chamadas para Test_Macronuncatêm parênteses aninhados, então existe um truque fácil. Primeiro mude cada )
caractere para uma nova linha e vice-versa. Em seguida, exclua todas as linhas que não contenham Test_Macro e remova tudo até Test_Macro. Neste ponto, uma parte do File2.txt processado ficaria assim
Test_Macro(abc, def, " string1 string2 test string",) "test string2 ",) 123456
Então agora precisamos converter as )
costas. Neste ponto você tem algumas opções. Eu sou a favor de usar sed para se livrar dos espaços extras ao mesmo tempo. Também precisamos adicionar novamente 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 Test_Macro incluam parênteses aninhados, você precisará usar armas significativamente maiores, pois precisará analisar a entrada em vez de apenas combiná-la com o padrão. (Em teoria, se você pode restringir o nível de aninhamento, então você pode combinar padrões, mas na prática isso fica muito complicado muito rapidamente e você deve desconsiderar essa abordagem). Existem estruturas de analisador para linguagens como python, ou você pode construir ferramentas sobre ferramentas como lex.
Responder2
Editar: esta resposta foi preparada antes da pergunta ser revisada. A forma original da pergunta incluía:
Quando tentei encontrar algum padrão usando "grep", ele imprimiu apenas a primeira linha. Mas eu quero até o final da chave.
Expressões regulares não podem contar, mas Sed pode fazer loop.
Aqui está um trecho Sed que irá capturar qualquer linha que contenha Test_Macro
a linha com o parêntese próximo apropriado,mesmo se houver parênteses aninhados:
#n
/Test_Macro/{
p;
:rep
s/([^()]*)//;
trep
/^[^(]*$/d;
h;
n;
p;
x;
G;
brep
}
Convertido para uma linha única, fica assim:
sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}'
A entrada e a saída ficam 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");
$
Responder3
Arquivo1:
$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*/\1/;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[^)]*);\).*/\1/;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... haha
$ sed '/Test_Macro/{N;$!N;s/[ ]*\\n//g;s/.*\(Test_Macro[^)]*);\).*/\1/;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 seja a última vez)... removendo a string "\n" quando estiver 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[^)]*);\)/\1/};' 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...
atualizar;
$ 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...