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 builde - 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 }