Encontre e substitua o conteúdo de um arquivo

4

Eu tenho um arquivo que começa com algumas instruções "include", como esta:

include foo.xyz
include bar.xyz
do c
do d

Suponha que o arquivo foo.xyz contenha do a e o arquivo bar.xyz contenha do b . Como posso escrever um script que substitua cada instrução include file.xyz pelos contextos de file.xyz ? Eu quero acabar com a seguinte saída:

do a
do b
do c
do d

Eu tentei a solução em " Substituir string por conteúdo de um arquivo usando sed "mas o nome do arquivo é codificado. Eu gostaria que o nome do arquivo fosse gerado dinamicamente, dependendo do argumento include .

    
por John Wickerson 11.11.2015 / 15:58

3 respostas

4

Aqui está uma versão recursiva simples com o awk. Você deve criar um script no seu PATH com

#!/bin/bash
awk '
$1=="include" && NF>=2 {
   system("'$0' " $2)
   next
}
{print}' "$@"

Ele supõe que nomes de arquivos não possuem caracteres especiais (incluindo espaços) neles. O awk verifica a primeira palavra para inclusão e, em seguida, chama o script para processar o arquivo fornecido como segunda palavra. Outras linhas são impressas. Note que o $0 aqui está fora das aspas simples do awk, então é um shell $0 , ie o nome do script.

    
por 11.11.2015 / 16:23
2
grep -n '^include ' yourfile |
sed  -e 's/:[^ ]* /{ r /'    \
     -e 'G;s/.$/&b&}/'       |
sed -nf - -ep       yourfile

isso deve funcionar. grep encontra os números de linha include , o primeiro sed modifica sua saída para os comandos [num]{r fname\nb\n} específicos da linha, e a segunda sed p rints a cada linha que não é t um desses os primeiros scripts para ele.

{   for   x in  a b
    do    echo "do $x">"file$x.xyz"
          echo "include file$x.xyz"
    done; printf "do %s\n"  c d
}   >yourfile
cat  yourfile
include filea.xyz
include fileb.xyz
do c
do d

Isso apenas gera sua amostra e mostra seu arquivo .

E isso funciona:

grep -n '^include ' yourfile |
sed  -e 's/:[^ ]* /{ r /'    \
     -e 'G;s/.$/&b&}/'       |
sed -nf - -ep       yourfile
do a
do b
do c
do d

os arquivos r ead podem ser de qualquer tamanho, embora, é claro, e não estejam restritos à única linha. Os próprios nomes de arquivos são restritos a uma única linha, mas são de outra forma mais ou menos irrestritos (dependendo do seu sed - alguns seds mais antigos tinham limites arbitrários de tamanho de nome, mas os mais usados atualmente não) .

    
por 11.11.2015 / 18:01
0
cat  $(grep '^include' file.txt | cut -d" " -f2); grep -v '^include' file.txt

O primeiro comando será grep da linha que começa com include em file.txt , cut a parte do nome do arquivo e, em seguida, cat it.

O próximo comando imprimirá todas as linhas, exceto a linha que começa com include em file.txt

    
por 11.11.2015 / 16:35