Как я могу найти и заменить определенные слова в текстовом файле с помощью командной строки?
Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок
Как я могу найти и заменить определенные слова в текстовом файле с помощью командной строки?
Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок
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, будучи утилитой для обработки текста, вполне подходит для такой задачи. Он может выполнять простые замены и гораздо более сложные, основанные на регулярные выражения. Он обеспечивает две функции: 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 - это еще один инструмент, который часто используется для обработки текста, но это язык общего назначения, который используется в сетях, системном администрировании, настольных приложениях и многих других местах. Он позаимствовал множество концепций / функций из других языков, таких как 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
%
выберите все строки
s
замена
g
замените все экземпляры в каждой строке
x
напишите, были ли внесены изменения (они были внесены), и выйдите
sed
это sтопать редитор, в том , что вы можете использовать |
(труба) для отправки стандартные потоки (в частности, STDIN и STDOUT) через sed
и изменять их программно на лету, что делает его удобным инструментом в традиции философии Unix; но также может редактировать файлы напрямую, используя -i
параметр, указанный ниже.
Учесть следующее:
sed -i -e 's/few/asd/g' hello.txt
s/
используется для sустановите найденное выражение few
с asd
:
Немногие, храбрые.
АСД, храбрый.
/g
расшифровывается как "глобальный", что означает сделать это для всей линии. Если вы откажетесь от /g
(с s/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 ] является файлом для поиска
Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок