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

347

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

    
задан Jon Doe 07.01.2011 в 05:10
источник

6 ответов

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

Пояснение:

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

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

ответ дан cscarney 07.01.2011 в 05:23
источник
21

Существует несколько способов сделать это. Один использует sed и Regex. SED - редактор потоков для фильтрации и преобразования текста. Один из примеров:

[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

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

[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
    
ответ дан Marco Ceppi 07.01.2011 в 05:26
13

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

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

Пример:

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

В приведенном выше примере все 1 заменены на 0 независимо от того, где он находится.

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

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

Пример:

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

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

Через Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
    
ответ дан Avinash Raj 02.07.2014 в 14:59
12

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

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

  2. s substitute

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

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

ответ дан Steven Penny 16.04.2016 в 20:36
9

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

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

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

BASH

Bash не предназначен для обработки текста, но простые замены можно выполнить с помощью расширения параметров , в частности здесь мы можем использовать простую структуру ${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

Этот небольшой скрипт не выполняет замену на месте, что означает, что вам нужно будет сохранить новый текст в новый файл и избавиться от старого файла или 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 - редактор строк. Он также использует регулярные выражения, но для простых подстановок достаточно:

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

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

Perl

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

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

Подобно sed, perl также имеет флаг -i.

Python

Этот язык очень универсален и также используется в самых разных приложениях. Он имеет множество функций для работы со строками, среди которых 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 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])

Этот сценарий должен быть вызван с input.txt в качестве аргумента командной строки.

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

    
ответ дан Sergiy Kolodyazhnyy 03.02.2017 в 08:49
4

sed - s tream ed itor , в котором вы можете использовать | (pipe) для отправки стандартных потоков (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 используется для редактирования i n места в файле hello.txt .

Параметр

-e указывает на выполнение e xpression / command, в данном случае s/ .

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

    
ответ дан Chaminda Bandara 23.11.2017 в 10:00