it-swarm.dev

Najděte a nahraďte text v souboru pomocí příkazů

Jak mohu najít a nahradit konkrétní slova v textovém souboru pomocí příkazového řádku?

723
Jon Doe
sed -i 's/original/new/g' file.txt

Vysvětlení:

  • sed = Stream Editor
  • -i = na místě (tj. uložit zpět do původního souboru)
  • Příkazový řetězec:

    • s = náhradní příkaz
    • original = regulární výraz popisující slovo, které má být nahrazeno (nebo jen samotné slovo)
    • new = text, který jej nahradí
    • g = global (tj. nahradit vše a ne pouze první výskyt)
  • file.txt = název souboru

1150
cscarney

Existuje mnoho různých způsobů, jak toho dosáhnout. Jeden používá sed a Regex. SED je Stream Editor pro filtrování a transformaci textu. Jeden příklad je následující:

[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

Jiný způsob, který může dávat větší smysl než < strin a > strout je s trubkami!

[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
34
Marco Ceppi

Existuje mnoho způsobů, jak toho dosáhnout. V závislosti na složitosti toho, čeho se člověk snaží dosáhnout pomocí nahrazení řetězce, a v závislosti na nástrojích, se kterými je uživatel obeznámen, mohou být některé metody preferovány více než jiné.

V této odpovědi používám jednoduchý soubor input.txt, Který můžete použít k vyzkoušení všech zde uvedených příkladů. Obsah souboru:

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

BASH

Bash není ve skutečnosti určen pro zpracování textu, ale jednoduché nahrazení lze provést pomocí rozšíření parametr , zejména zde můžeme použít jednoduchou strukturu ${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

Tento malý skript nedělá náhradu na místě, což znamená, že budete muset uložit nový text do nového souboru a zbavit se starého souboru nebo mv new.txt old.txt

Vedlejší poznámka: pokud jste zvědaví, proč se používá while IFS= read -r ; do ... done < input.txt, Je to v podstatě způsob, jakým Shell čte řádky po řádku. Viz this pro informaci.

AWK

AWK jako nástroj pro zpracování textu je pro takový úkol docela vhodný. Může provádět jednoduché nahrazení a mnohem pokročilejší na základě regulární výrazy . Poskytuje dvě funkce: sub() a gsub(). První nahradí pouze první výskyt, zatímco druhý nahradí výskyt v celém řetězci. Pokud například máme řetězec one potato two potato, Bude to výsledek:

$ 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 může brát vstupní argument jako argument, takže dělat stejné věci s input.txt, By bylo snadné:

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

V závislosti na verzi AWK, kterou máte, může nebo nemusí mít úpravy na místě, proto je obvyklým postupem ukládání a nahrazování nového textu. Například něco takového:

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

SED

Sed je editor linek. Používá také regulární výrazy, ale pro jednoduché substituce stačí:

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

Dobré je, že tento nástroj má místní úpravy, které můžete povolit pomocí příznaku -i.

Perl

Perl je další nástroj, který se často používá pro zpracování textu, ale je to jazyk pro všeobecné účely a používá se v sítích, správě systému, desktopových aplikacích a na mnoha dalších místech. Půjčilo si mnoho konceptů/funkcí z jiných jazyků, jako je C, sed, awk a další. Jednoduché nahrazení lze provést takto:

Perl -pe 's/blue/Azure/' input.txt

Stejně jako sed má Perl také vlajku -i.

Python

Tento jazyk je velmi všestranný a používá se také v široké škále aplikací. Má mnoho funkcí pro práci s řetězci, mezi nimiž je replace(), takže pokud máte proměnnou typu var="Hello World", Můžete udělat var.replace("Hello","Good Morning")

Jednoduchý způsob čtení souboru a nahrazení řetězce v něm by byl takový:

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

S Pythonem však musíte také vytvořit výstup do nového souboru, který můžete také provést v samotném skriptu. Zde je například jednoduchý:

#!/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])

Tento skript má být vyvolán s input.txt Jako argument příkazového řádku. Přesný příkaz ke spuštění python skript s argumentem příkazového řádku by byl)

 $ ./myscript.py input.txt

nebo

$ python ./myscript.py input.txt

Samozřejmě se ujistěte, že ./myscript.py Je ve vašem aktuálním pracovním adresáři, a nejprve se ujistěte, že je nastavitelný jako chmod +x ./myscript.py

Python může mít také regulární výrazy, zejména je zde modul re, který má funkci re.sub(), kterou lze použít pro pokročilejší náhrady.

29

Vim můžete použít v Ex režimu:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % vyberte všechny řádky

  2. s náhradní

  3. g nahradí všechny instance v každém řádku

  4. x zápis, pokud byly provedeny změny (mají) a opuštění

22
Steven Penny

Prostřednictvím příkazu awk's gsub

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

Příklad:

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

Ve výše uvedeném příkladu jsou všechny hodnoty 1 nahrazeny čísly 0 bez ohledu na sloupec, kde jsou umístěny.


Pokud chcete provést náhradu v konkrétním sloupci, udělejte to takto,

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

Příklad:

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

Nahrazuje hodnotu 1 číslem 0 pouze v prvním sloupci.

Prostřednictvím Perlu

$ echo 'foo' | Perl -pe 's/foo/bar/g'
bar
21
Avinash Raj

sed je s tream ed itor v tom, že můžete použít | (pipe) k odeslání standardní toky (konkrétně STDIN a STDOUT) prostřednictvím sed a programově je změnit za běhu, což z něj činí užitečný nástroj v unixové filozofické tradici; ale lze také upravovat soubory přímo pomocí níže uvedeného parametru -i.
Zvažte následující :

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

s/ Se používá k s ubstituci nalezeného výrazu few s asd:

Těch pár, statečných.


ASD, statečný.

/g Znamená „global“, což znamená, že to bude dělat pro celou řadu. Pokud vynecháte /g (S s/few/asd/, Vždy musí být tři lomítka bez ohledu na to) a few se objeví dvakrát na stejném řádku, pouze první few se mění na asd:

Těch pár mužů, těch pár žen, statečných.


Asd muži, těch pár žen, statečných.

To je užitečné za určitých okolností, jako je například změna zvláštních znaků na začátku řádků (například nahrazení symbolů vyšších než někteří lidé používají k citování předchozího materiálu v e-mailových vláknech vodorovnou kartou, zatímco citovanou algebraickou nerovnost ponecháte později v řádku) nedotčený), ale ve vašem příkladu, kde určíte, že nastane kdekolifew, měl by být nahrazen, ujistěte se, že máte tento /g.

Následující dvě možnosti (příznaky) jsou sloučeny do jedné -ie:

Volba -i Se používá k úpravě i n místa v souboru hello.txt.

Možnost -e Označuje e xpression/příkaz ke spuštění, v tomto případě s/.

Poznámka: Je důležité použít -i -e Pro vyhledávání/nahrazení. Pokud uděláte -ie, Vytvoříte zálohu každého souboru s připojeným písmenem „e“.

8
Chaminda Bandara

Můžete to udělat takto:

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

Příklady: Chcete-li nahradit všechny výskyty [logdir ',' '] (bez []) za [logdir', os.getcwd ()] ve všech souborech, které jsou výsledkem příkazu locate, proveďte následující kroky:

ex1:

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"

ex2:

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

kde [tensorboard/program.py] je soubor pro vyhledávání

2