Script Bash para substituir um arquivo se ele tiver uma string específica [closed]

2

Eu tenho uma lista de arquivos que eu quero verificar para uma determinada string. Se a string existir no arquivo, quero substituí-la por uma nova versão que possua. Qual é a maneira mais fácil de fazer isso?

    
por Alexander 01.12.2010 / 18:56

5 respostas

4

for file in "'grep -l "foo" bar gazi'"; do cp -p --backup=numbered replace "$file"; done

onde substituir é o caminho para o arquivo de substituição, bar e gazi representam uma lista de arquivos a serem verificados, e foo é a string de pesquisa de interesse.

Se você precisar de ajuda adicional para formular uma expressão regular apropriada para o grep (acima), por favor, não hesite em perguntar.

    
por 01.12.2010 / 19:04
3

O grep pode pesquisar um arquivo em busca de uma string e retornará 0 se for encontrado, você pode usar isso como parte de uma condicional para substituir o arquivo, algo como:

 #!/bin/bash
 if [ !'/bin/grep -q teststring /path/to/file' ]; then
    cp newfile oldfile
 fi
    
por 01.12.2010 / 19:02
1

Presumivelmente, você tem um arquivo com a lista de arquivos nele? Não sei se você tem um arquivo estático com o qual você está substituindo arquivos correspondentes ou um possível substituto por arquivo. Isso lida com o segundo caso, para o primeiro, apenas substitua $ i.new pelo nome do arquivo estático.

for i in 'cat /var/tmp/listoffiles' ; do
    if grep string $i > /dev/null 2>&1 ; then
        cp $i $i.old
        cp $i.new $i
    fi
done
    
por 01.12.2010 / 19:24
0

Embora eu concorde com todos os testes do grep, o sed pode fazer isso sem um teste realmente.

sed -i.BACKUP / STRING QUE VOCÊ DESEJA REPLACE / NEW STRING / 'file

Se a string não estiver lá, não fará nada. Só vale a pena mencionar. De sua pergunta eu não tinha certeza se você estava tentando substituir o arquivo inteiro ou apenas uma string dentro dele.

    
por 01.12.2010 / 19:35
0

A maneira correta de processar arquivos em um loop em um script de shell é direcionar o comando para while ou redirecionar um arquivo para a instrução done de um loop while . Isso manipulará qualquer nome, exceto aqueles que contiverem novas linhas. Você não deve usar o formulário for f in $(cmd) .

Neste exemplo, find é o comando que produz a lista de arquivos:

find . -type f -name "*.txt" | while read -r filename
do
    if grep -qs "$string" "$filename"  # or use >/dev/null 2>&1 instead of -qs
    then
        cp "$replacement" "$filename"
    fi
done

ou, aqui, a lista está contida em um arquivo:

while read -r filename
...
done < "$file_with_list"

Outro método é usar xargs .

Para um comando que produz a lista de arquivos (por exemplo, find ):

find . -type f -name "*.txt" -print0 | xargs -0 -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement_file "%"'

O método anterior funcionará nos casos em que nomes de arquivos podem incluir novas linhas.

Se a lista estiver em um arquivo:

xargs -a "$file_with_list" -I % env string=$string sh 'grep -qs "$string" "%" && cp replacement "%"'

Todos esses exemplos funcionarão nos casos em que nomes de arquivos podem incluir espaços.

    
por 02.12.2010 / 00:40

Tags