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


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


434
2018-01-07 04:10


origine


Maggio del tuo interesse github.com/lucio-martinez/rch :-) - Lucio


risposte:


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 con cui sostituirlo
    • g = globale (cioè sostituisci tutto e non solo la prima occorrenza)
  • file.txt = il nome del file


724
2018-01-07 04:23



@ mcExchange Se è specificamente il / carattere che devi abbinare, puoi semplicemente usare un altro carattere come separatore (ad es. 's_old/text_new/text_g'). Altrimenti, puoi mettere un \  prima di qualsiasi $ * . [ \ ^ per ottenere il carattere letterale. - cscarney
@BrianZ Per quanto riguarda il file system, l'output di sed è un nuovo file con lo stesso nome. È uno dei bug comunemente segnalati che non sono bug - cscarney
Potresti volere s/\boriginal\b/new/g invece di s/original/new/g (\b corrisponde a un limite di parole) per sostituire solo le parole intere. - Chris Martin
Il comando OSX sed -i '.bak' 's/original/new/g' file.txt può anche essere eseguito con un'estensione di lunghezza zero sed -i '' 's/original/new/g' file.txt, che non genererà alcun backup. - Kirk
Gli utenti MacOS dovranno aggiungere "" "dopo -i come parametro per -i ed.gs/2016/01/26/os-x-sed-invalid-command-code in modo che il file venga sovrascritto. - geoyws


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:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

Un altro modo che può avere più senso di < strin e > strout è con i tubi!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog

26
2018-01-07 04:26



notare la cat in cat file | sed '...' è inutile Puoi dire direttamente sed '...' file. - fedorqui
In effetti questo può essere ulteriormente ridotto: sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly prenderà il file yarly e farà le 2 modifiche sul posto mentre fa un backup. utilizzando time bash -c "$COMMAND" a tempo suggerisce che questa versione è un ~ 5 volte più veloce. - pbhj


Puoi usare Vim in modalità Ex:

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

  2. s sostituire

  3. g sostituire tutte le istanze in ogni riga

  4. x scrivere se sono state apportate modifiche (hanno) e uscire


15
2018-04-16 18:36





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",$1);}' file

Sostituisce 1 con 0 solo sulla colonna 1.

Attraverso Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar

14
2017-07-02 12:59



L'ho usato sul terminale MacOS e non ha fatto nulla ... - Jim


C'è una moltitudine di 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 usando semplice input.txt file, che è possibile 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 è possibile eseguire semplici sostituzioni tramite 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, il che significa che 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 del perché while IFS= read -r ; do ... done < input.txt è usato, è fondamentalmente il modo in cui la shell legge il file riga per riga. Vedere 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 una 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 pratica abituale è 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 righe. Utilizza anche le espressioni regolari, ma per le sostituzioni semplici è sufficiente fare:

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

Ciò che è positivo in questo strumento è che dispone di modifiche sul posto, che è possibile abilitare con -i bandiera.

Perl

Perl è un altro strumento che viene spesso utilizzato per l'elaborazione del testo, ma è un linguaggio generico e viene utilizzato in rete, 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 fatta in questo modo:

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

Come sed, perl ha anche la bandiera -i.

Pitone

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 c'è replace(), quindi se hai variabile come var="Hello World" , potresti farlo 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, è necessario anche eseguire l'output su un nuovo file, che è possibile eseguire anche all'interno dello 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'è re modulo, che ha re.sub() funzione, che può essere utilizzata per sostituzioni più avanzate.


12
2018-02-03 07:49





sed è il Stream Editor, in quanto puoi usare | (pipe) da inviare flussi standard (STDIN e STDOUT in particolare) attraverso sed e modificarli al volo al volo, rendendolo uno strumento utile nella tradizione filosofica Unix; ma può anche modificare direttamente i file usando il -i parametro indicato di seguito.
Considera quanto segue:

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

s/ è abituato a Ssostituire l'espressione trovata few con asd:

I pochi, i coraggiosi.


Il asd, il coraggioso.

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

I pochi uomini, le poche donne, i coraggiosi.


Gli uomini asd, le poche donne, i coraggiosi.

Ciò è 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ù avanti nella riga intatto), ma nel tuo esempio in cui lo specifichi dovunque  few si verifica dovrebbe essere sostituito, assicurarsi di averlo /g.

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

-i l'opzione è usata per modificare ion posto sul file hello.txt.

-e l'opzione indica il expression / comando da eseguire, in questo caso s/.

Nota: è importante che tu lo usi -i -e per cercare / sostituire. Se fate -ie, si crea un backup di ogni file con la lettera 'e' aggiunta.


6
2017-11-23 09:00





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, fare:

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

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


0
2017-07-24 02:13



Ciao. La tua scelta di stringhe (logdir', '' -> /logdir', os.getcwd()) rende difficile la risposta a questa risposta. Inoltre, vale la pena specificare che la tua risposta individua prima i file da utilizzare, perché non fa parte della domanda. - mwfearnley
Salve, questa risposta è sia di ricerca che di sostituzione se trova <testo vecchio> nel file. - Nguyễn Tuấn Anh
Scelgo questa risposta per tutto quello che usano tensore in keras, che vogliono cambiare comando da: tensorboard --logdir = '/ percorso / a / log / cartella /' da usare: solo tensore, quando si rimane nella cartella dei registri. è molto conveniente - Nguyễn Tuấn Anh