Поиск и замена текста в файле с помощью команд

Как я могу найти и заменить определенные слова в текстовом файле с помощью командной строки?

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

Объяснение:

  • sed = Редактор потоков
  • -i = на месте (т.е. сохранить обратно в исходный файл)
  • Командная строка:

    • s = команда замены
    • original = регулярное выражение, описывающее слово для замены (или только само слово)
    • new = текст, который нужно заменить на
    • g = глобальный (т.е. заменить все, а не только первое вхождение)
  • file.txt = имя файла

Есть множество способов достичь этого. В зависимости от сложности того, чего пытаются достичь с помощью замены строк, и в зависимости от инструментов, с которыми знаком пользователь, некоторые методы могут быть предпочтительнее других.

В этом ответе я использую простой input.txt файл, который вы можете использовать для тестирования всех представленных здесь примеров. Содержимое файла:

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

удар

Bash на самом деле не предназначен для обработки текста, но простые замены могут быть выполнены с помощью расширение параметров , в частности, здесь мы можем использовать простую структуру ${parameter/old_string/new_string}.

#!/bin/bashwhile IFS= read -r linedo    case "$line" in       *blue*) printf "%s\n" "${line/blue/azure}" ;;       *) printf "%s\n" "$line" ;;    esacdone < input.txt

Этот небольшой скрипт не выполняет замену на месте, что означает, что вам придется сохранить новый текст в новый файл и избавиться от старого файла, или mv new.txt old.txt

Примечание: если вам интересно, почему while IFS= read -r ; do ... done < input.txt используется, это в основном способ оболочки читать файл построчно. Видеть этот для справки.

awk

AWK, будучи утилитой для обработки текста, вполне подходит для такой задачи. Он может выполнять простые замены и гораздо более сложные, основанные на регулярные выражения. Он обеспечивает две функции: sub() и gsub(). Первый заменяет только первое вхождение, в то время как второй - заменяет вхождения во всей строке. Например, если у нас есть строка one potato two potato , это было бы результатом:

$ 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 может принимать входной файл в качестве аргумента, поэтому делает то же самое с input.txt , было бы легко:

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

В зависимости от версии AWK, которая у вас есть, она может иметь или не иметь редактирования на месте, поэтому обычной практикой является сохранение и замена нового текста. Например, что-то вроде этого:

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

СЕД

Sed - это редактор строк. Он также использует регулярные выражения, но для простых замен достаточно выполнить:

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

Что хорошо в этом инструменте, так это то, что в нем есть редактирование на месте, которое вы можете включить с помощью -i флаг.

Perl

Perl - это еще один инструмент, который часто используется для обработки текста, но это язык общего назначения, который используется в сетях, системном администрировании, настольных приложениях и многих других местах. Он позаимствовал множество концепций / функций из других языков, таких как C, sed, awk и других. Простая замена может быть выполнена следующим образом:

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

Как и sed, perl также имеет флаг -i.

Питон

Этот язык очень универсален и также используется в самых разных приложениях. Он имеет множество функций для работы со строками, среди которых replace(), так что если у вас есть переменная, подобная var="Hello World" , вы могли бы сделать var.replace("Hello","Good Morning")

Простой способ прочитать файл и заменить строку в нем будет выглядеть следующим образом:

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

Однако в Python вам также необходимо выполнить вывод в новый файл, что вы также можете сделать из самого скрипта. Например, вот простой пример:

#!/usr/bin/env pythonimport sysimport osimport tempfiletmp=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])

Этот скрипт должен вызываться с помощью input.txt в качестве аргумента командной строки. Точная команда для запуска скрипта python с аргументом командной строки будет

 $ ./myscript.py input.txt

или

$ python ./myscript.py input.txt

Конечно, убедитесь, что ./myscript.py находится в вашем текущем рабочем каталоге, и для первого способа убедитесь, что он установлен исполняемым с chmod +x ./myscript.py

Python также может иметь регулярные выражения, в частности, есть re модуль, который имеет re.sub() функция, которая может быть использована для более продвинутых замен.

Существует несколько различных способов сделать это. Один из них использует sed и регулярное выражение. SED - это потоковый редактор для фильтрации и преобразования текста. Один из примеров заключается в следующем:

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

Другой способ, который может иметь больше смысла, чем < strin и > strout это с трубами!

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

Через команду awk gsub,

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

Пример:

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

В приведенном выше примере все 1 заменяются на 0, независимо от столбца, в котором он находится.


Если вы хотите выполнить замену в определенном столбце, то сделайте это следующим образом,

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

Пример:

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

Он заменяет 1 на 0 только в первом столбце.

Через Perl,

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

Вы можете использовать Vim в режиме Ex:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % выберите все строки

  2. s замена

  3. g замените все экземпляры в каждой строке

  4. x напишите, были ли внесены изменения (они были внесены), и выйдите

sed это sтопать редитор, в том , что вы можете использовать | (труба) для отправки стандартные потоки (в частности, STDIN и STDOUT) через sed и изменять их программно на лету, что делает его удобным инструментом в традиции философии Unix; но также может редактировать файлы напрямую, используя -i параметр, указанный ниже.
Учесть следующее:

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

s/ используется для sустановите найденное выражение few с asd:

Немногие, храбрые.


АСД, храбрый.

/g расшифровывается как "глобальный", что означает сделать это для всей линии. Если вы откажетесь от /gs/few/asd/, всегда должно быть три косых черты, несмотря ни на что) и few появляется дважды в одной и той же строке, только первый few изменяется на asd:

Несколько мужчин, несколько женщин, храбрых.


Мужчины с РАС, несколько женщин, храбрые.

Это полезно в некоторых обстоятельствах, например, при изменении специальных символов в начале строк (например, при замене символов "больше", которые некоторые люди используют для цитирования предыдущих материалов в потоках электронной почты, на горизонтальную вкладку, оставляя алгебраическое неравенство в кавычках позже в строке нетронутым), но в вашем примере, где вы указываете это везде few если его следует заменить, убедитесь, что у вас есть это /g.

Следующие два параметра (флаги) объединены в один, -ie:

-i опция используется для редактирования in место в файле hello.txt.

-e опция указывает на expression/команда для запуска, в этом случае s/.

Примечание: Важно, чтобы вы использовали -i -e для поиска/замены. Если вы это сделаете -ie, вы создаете резервную копию каждого файла с добавлением буквы "e".

Вы можете сделать вот так:

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

Примеры:чтобы заменить все вхождения [logdir', "] (без []) на [logdir', os.getcwd()] во всех файлах, являющихся результатом команды locate, выполните:

пример 1:

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

пример 2:

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

где [tensorboard/program.py ] является файлом для поиска