Crie arquivos a partir de modelos, substituições no meio de outras palavras

1

Existe uma maneira de convencer o m4 a substituir uma macro no meio de uma palavra?

Eu gostaria desse arquivo, day.m4:

define(Sat,Cat)dnl
Saturday

e este comando:

m4 day.m4

para produzir esta saída:

Caturday

Como mostrado, o m4 não fará isso.

Alternativamente, existe uma maneira de obter sed para executar várias substituições simultaneamente? Ou seja, sem passar o arquivo para cada substituição.

Eu posso canalizar vários comandos sed juntos ou usar uma combinação de sed e m4 e isso não é tão ruim, mas se houver uma maneira conveniente de fazer isso com um arquivo de entrada e um comando que seria preferível.

Qualquer outra ferramenta comumente disponível também seria boa.

Meu objetivo é usar isso para criar arquivos a partir de modelos. A maioria dos tokens a serem substituídos são separados por espaços.

    
por Praxeolitic 17.09.2014 / 00:30

2 respostas

0

Parece que tudo o que você precisa é:

sed -e sub1 -e sub2 file

Onde sub tem o formulário:

s/sat/cat/g

Você também pode colocar todas as suas substituições em um arquivo e executá-lo com:

sed -f scriptfile filetomodify
    
por 13.02.2015 / 23:23
0

Usando patsubst ()

m4 fornece uma função de pesquisa e substituição, que pode realizar substituições em qualquer lugar, inclusive no meio da palavra, chamado patsubst :

Builtin: patsubst (string, regexp, [replacement])

Searches string for matches of regexp, and substitutes replacement for each match.

Isso não envolve a configuração de uma nova definição, portanto, ela não pode ser aplicada por padrão a todas as entradas futuras. Em vez disso, você terá que "inserir" o texto de entrada completo dentro da chamada de função:

patsubst(dnl
[...]
Saturday
[...]
,'Sat','Cat')dnl

Usando a mudança ()

m4 também fornece mudança de palavra :

A file being processed by m4 is split into quoted strings, words (potential macro names) and simple tokens (any other single character). Initially a word is defined by the following regular expression:

[_a-zA-Z][_a-zA-Z0-9]*

Using changeword, you can change this regular expression:

Infelizmente, a função changeword não é padrão. Só está disponível se você solicitou com --enable-changeword em tempo de compilação.

Com isso ativado, você poderia, por exemplo. forçar m4 a aceitar apenas palavras de três letras.

define('Sat','Cat')dnl
changeword('[A-Za-z][a-z]?[a-z]?')dnl
Saturday

Mas changeword tem problemas adicionais:

regex must obey the constraint that every prefix of the desired final pattern is also accepted by the regular expression.

[...]

Tightening the lexical rules is less useful, because it will generally make some of the builtins unavailable.

O padrão acima evitaria outras definições (apenas reconhece dnl porque são exatamente três letras). Então, além de não ser padrão, não é adequado para o que você está tentando fazer.

    
por 27.11.2018 / 18:30