Eu não consegui descobrir imediatamente como fazer isso em sed
sem assumir que há pelo menos um caractere
que é conhecido nunca aparecer na entrada.
Eu assumi que #
nunca aparecerá na entrada (ou na sua palavra adicionada).
Isso parece funcionar:
sed '/read build/ {
s/{/{ /
: fruit
s/\({.*\) \([^}# ][^ ]*\)/#MY_WORD/
t fruit
s/#/ /g
s/{ /{/
}'
Nas linhas que contêm read build
Primeiro, insere um espaço após o {
.
Em seguida, ele procura por um espaço que está em algum lugar depois de um {
e imediatamente antes de uma palavra (presumivelmente um nome de arquivo).
Substitui o espaço por #
, insere sua palavra,
e volta e procura por mais.
( fruit
é um rótulo de loop arbitrário.)
Depois de encontrá-los, todos os caracteres #
retornam aos espaços,
e remove o espaço que ele inseriu (após o {
).
Além do bit sobre #
não ocorrendo na entrada,
isso pressupõe que
-
}
é o último caractere não vazio em cada linharead build
e - espaços em branco são apenas espaços; sem guias.
Em awk
:
awk '/read build/ {
in_braces=0
for (i = 1; i <= NF; i++) {
if ($i == "{") in_braces=1
else if (substr($i,1,1) == "{") {
$i = "{MYWORD" substr($i,2)
in_braces=1
}
else if ($i == "}") in_braces=0
else if (in_braces) $i = "MY_WORD" $i
}
}
{ print }'
Para cada linha read build
,
Ele percorre todas as palavras (campos) na linha.
Ele usa uma variável de estado ( in_braces
)
para acompanhar se está entre {
e }
;
se for, modifica cada palavra para começar com sua palavra adicionada.
Observe que ele precisa lidar com dois casos ligeiramente diferentes:
- se uma palavra for
{
, defina o sinalizador para começar a modificar todas as palavras subsequentes e - se uma palavra começa com
{
, é na verdade um composto da forma{fileX
, então modifique it para ser a concatenação de{
, a palavra adicionada e o nome do arquivofileX
. E também defina o sinalizador para modificar todas as palavras subsequentes.
Enquanto isso permite separadores como separadores de palavras, tem a fraqueza que colapsa o espaço em branco em um único espaço. Então, por exemplo, a entrada
read build { file1 file2 file3 }
produziria a saída
read build { MY_WORDfile1 MY_WORDfile2 MY_WORDfile3 }
Além disso, isso pressupõe que
- o
{
está no início de uma palavra (ou seja, tem espaço em branco antes disso), e - ou
}
é o último caractere não em branco em cada linharead build
, ou é uma palavra separada (ou seja, tem espaços em branco antes e depois)
Permite múltiplos conjuntos de chaves; por exemplo,
read build { file1 file2 file3 } text to be left alone { file4 file5 file6 }