Trova e sostituisci il testo all'interno di un file usando i comandi

428

Come posso trovare e sostituire parole specifiche in un file di testo utilizzando la riga di comando?

    
posta Jon Doe 07.01.2011 - 05:10

7 risposte

713
sed -i 's/original/new/g' file.txt

Spiegazione:

  • sed = Stream Editor
  • -i = in-place (cioè salva il file originale)
  • La stringa di comando:

    • s = il comando sostitutivo
    • original = un'espressione regolare che descrive la parola da sostituire (o solo la parola stessa)
    • new = il testo per sostituirlo con
    • g = globale (ad esempio, sostituisci tutto e non solo la prima occorrenza)
  • file.txt = il nome del file

risposta data cscarney 07.01.2011 - 05:23
26

Ci sono diversi modi per farlo. Uno sta usando sed e Regex. SED è un editor di stream per filtrare e trasformare il testo. Un esempio è il seguente:

[email protected]: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
[email protected]: ~$ sed s/slow/quick/ < orly > yarly
[email protected]: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

Un altro modo che potrebbe avere più senso di < strin e > strout è con pipe!

[email protected]: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
[email protected]: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog
    
risposta data Marco Ceppi 07.01.2011 - 05:26
15

Puoi usare Vim in modalità Ex:

ex -sc '%s/OLD/NEW/g|x' file
  1. % seleziona tutte le linee

  2. s sostituto

  3. g sostituisce tutte le istanze in ogni riga

  4. x scrivi se le modifiche sono state apportate (hanno) e escono

risposta data Steven Penny 16.04.2016 - 20:36
14

Attraverso il comando gsub di awk,

awk '{gsub(/pattern/,"replacement")}' file

Esempio:

awk '{gsub(/1/,"0");}' file

Nell'esempio precedente, tutti gli 1 sono sostituiti da 0 indipendentemente dalla colonna in cui si trova.

Se vuoi fare una sostituzione su una colonna specifica, fai come questo,

awk '{gsub(/pattern/,"replacement",column_number)}' file

Esempio:

awk '{gsub(/1/,"0",);}' file

Sostituisce 1 con 0 solo sulla colonna 1.

Tramite Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
    
risposta data Avinash Raj 02.07.2014 - 14:59
12

Ci sono moltissimi modi per raggiungerlo. A seconda della complessità di ciò che si cerca di ottenere con la sostituzione di stringhe e in base agli strumenti con cui l'utente è familiare, alcuni metodi possono essere preferiti più di altri.

In questa risposta sto utilizzando un semplice file input.txt , che puoi utilizzare per testare tutti gli esempi forniti qui. Il contenuto del file:

roses are red , violets are blue
This is an input.txt and this doesn't rhyme

BASH

Bash non è pensato per l'elaborazione del testo, ma semplici sostituzioni possono essere fatte tramite l'espansione dei parametri , in particolare qui possiamo usare la struttura semplice ${parameter/old_string/new_string} .

#!/bin/bash
while IFS= read -r line
do
    case "$line" in
       *blue*) printf "%s\n" "${line/blue/azure}" ;;
       *) printf "%s\n" "$line" ;;
    esac
done < input.txt

Questo piccolo script non esegue la sostituzione sul posto, ovvero dovrai salvare il nuovo testo in un nuovo file e liberarti del vecchio file o mv new.txt old.txt

Nota a margine: se sei curioso di sapere perché viene utilizzato while IFS= read -r ; do ... done < input.txt , è fondamentalmente il modo in cui la shell legge il file riga per riga. Vedi questo per riferimento.

AWK

AWK, essendo un'utilità di elaborazione del testo, è abbastanza appropriato per tale compito. Può fare semplici sostituzioni e molto più avanzate basate su espressioni regolari . Fornisce due funzioni: sub() e gsub() . Il primo sostituisce solo la prima occorrenza, mentre il secondo sostituisce le occorrenze nell'intera stringa. Ad esempio, se abbiamo stringa one potato two potato , questo sarebbe il risultato:

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana

$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      
one banana two potato 

AWK può prendere un file di input come argomento, quindi fare le stesse cose con input.txt , sarebbe facile:

awk '{sub(/blue/,"azure")}1' input.txt

A seconda della versione di AWK che hai, può o non può avere una modifica sul posto, quindi la solita pratica è salvare e sostituire il nuovo testo. Ad esempio qualcosa del genere:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed è un editor di riga. Utilizza anche le espressioni regolari, ma per le sostituzioni semplici è sufficiente fare:

sed 's/blue/azure/' input.txt

Il bello di questo strumento è che ha una modifica sul posto, che puoi abilitare con -i flag.

Perl

Perl è un altro strumento che viene spesso utilizzato per l'elaborazione del testo, ma è un linguaggio generico e viene utilizzato in reti, amministrazione di sistema, app desktop e molti altri luoghi. Ha preso in prestito molti concetti / caratteristiche da altri linguaggi come C, sed, awk e altri. La semplice sostituzione può essere eseguita in questo modo:

perl -pe 's/blue/azure/' input.txt

Come sed, perl ha anche il flag -i.

Python

Questo linguaggio è molto versatile e viene anche utilizzato in un'ampia varietà di applicazioni. Ha molte funzioni per lavorare con le stringhe, tra le quali replace() , quindi se hai variabile come var="Hello World" , potresti fare var.replace("Hello","Good Morning")

Un modo semplice per leggere il file e sostituire la stringa in esso sarebbe come tale:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

Con Python, tuttavia, devi anche generare un nuovo file, che puoi anche eseguire dallo script stesso. Ad esempio, ecco una semplice:

#!/usr/bin/env python
import sys
import os
import tempfile

tmp=tempfile.mkstemp()

with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
    for line in fd1:
        line = line.replace('blue','azure')
        fd2.write(line)

os.rename(tmp[1],sys.argv[1])

Questo script deve essere chiamato con input.txt come argomento della riga di comando.

Python può anche avere espressioni regolari, in particolare c'è il modulo re , che ha la funzione re.sub() , che può essere usata per le sostituzioni più avanzate.

    
risposta data Sergiy Kolodyazhnyy 03.02.2017 - 08:49
6

sed è il s tream ed itor , in quanto è possibile utilizzare | (pipe) per inviare stream standard (STDIN e STDOUT in particolare) a sed e modificarli a livello di codice sul volare, rendendolo uno strumento utile nella tradizione filosofica Unix; ma puoi anche modificare i file direttamente, utilizzando il parametro -i menzionato di seguito.
Considera quanto segue :

sed -i -e 's/few/asd/g' hello.txt

s/ è usato per s sostituire l'espressione trovata few con asd :

  

I pochi, i più coraggiosi.

     

The asd, the brave.

/g sta per "global", che significa fare questo per l'intera linea. Se si omette /g (con s/few/asd/ , devono sempre esserci tre barre non importa quale) e few appare due volte sulla stessa riga, solo il primo few viene modificato in asd :

  

I pochi uomini, le poche donne, i coraggiosi.

     

Gli uomini asd, le poche donne, i coraggiosi.

Questo è utile in alcune circostanze, come alterare i caratteri speciali all'inizio delle righe (ad esempio, sostituendo i simboli più grandi di alcune persone usano per citare il materiale precedente nei thread email con una tabulazione orizzontale lasciando una ineguaglianza algebrica quotata più tardi nella riga non toccata), ma nel tuo esempio in cui specifichi che dovunque few si verifica dovrebbe essere sostituito, assicurati di avere quel /g .

Le seguenti due opzioni (flag) sono combinate in una, -ie :

L'opzione

-i viene utilizzata per modificare i n posto sul file hello.txt .

L'opzione

-e indica il comando e xpression / da eseguire, in questo caso s/ .

Nota: è importante utilizzare -i -e per cercare / sostituire. Se fai -ie , crei un backup di ogni file con la lettera 'e' aggiunta.

    
risposta data Chaminda Bandara 23.11.2017 - 10:00
0

Puoi fare così:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

Esempi: per sostituire tutte le occorrenze [logdir ',' '] (senza []) con [logdir', os.getcwd ()] in tutti i file risultanti dal comando locate, fai:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

dove [tensorboard / program.py] è il file da cercare

    
risposta data Nguyễn Tuấn Anh 24.07.2018 - 04:13

Leggi altre domande sui tag