Відповіді:
sed -i 's/original/new/g' file.txt
Пояснення:
sed
= Редактор потоку-i
= на місці (тобто зберегти назад у вихідний файл)Командний рядок:
s
= команда заміщенняoriginal
= регулярний вираз, що описує слово, яке потрібно замінити (або просто саме слово)new
= текст для заміниg
= глобальний (тобто замінити все, а не лише перше виникнення)file.txt
= ім'я файлу
sed
вони відповідають їм. Додайте -r
прапор, якщо ви хочете замість цього використовувати розширені RE.
/
символ, то ви можете просто використовувати якийсь інший символ як роздільник (наприклад 's_old/text_new/text_g'
). В іншому випадку ви можете поставити \
перед будь-яким із них, $ * . [ \ ^
щоб отримати буквальний характер.
sed -i '.bak' 's/original/new/g' file.txt
можна також запустити з розширенням нульової довжини sed -i '' 's/original/new/g' file.txt
, що не створить резервного копіювання.
Існує ряд різних способів зробити це. Один використовує sed
і Regex. SED - це редактор потоку для фільтрації та перетворення тексту. Один з таких прикладів:
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
Інший спосіб , який може мати більше сенсу , ніж < strin
та > strout
є з трубами!
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
cat
в cat file | sed '...'
- непотрібно. Можна прямо сказати sed '...' file
.
sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
зніматимете файл та зробимо 2 зміни на місці, роблячи резервну копію. Використовуючи time bash -c "$COMMAND"
час, це дозволяє припустити, що ця версія в 5 разів швидша.
Існує безліч способів цього досягти. Залежно від складності того, що намагається досягти із заміною рядків, та залежно від інструментів, з якими користувач знайомий, деякі методи можуть віддавати перевагу більше, ніж інші.
У цій відповіді я використовую простий input.txt
файл, який ви можете використовувати для тестування всіх наведених тут прикладів. Вміст файлу:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
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, будучи утилітою для обробки тексту, цілком підходить для такого завдання. Він може робити прості заміни та значно вдосконаленіші, засновані на регулярних виразах . Він забезпечує дві функції: 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 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 з аргументом командного рядка
$ ./myscript.py input.txt
або
$ python ./myscript.py input.txt
Звичайно, переконайтеся, що він ./myscript.py
знаходиться у вашому поточному робочому каталозі, і, перш за все, переконайтеся, що він встановлений у виконанніchmod +x ./myscript.py
Python також може мати регулярні вирази, зокрема, є re
модуль, який має re.sub()
функцію, яку можна використовувати для більш вдосконалених замін.
tr
команди в unix
tr
це ще один чудовий інструмент, але зауважте, що він призначений для заміни наборів символів (наприклад, це tr abc cde
було б перекладом a
на c
, b
на d
. Це трохи відрізняється від заміни цілих слів, як з sed
абоpython
Ви можете використовувати Vim в режимі Ex:
ex -s -c '%s/OLD/NEW/g|x' file
%
виберіть усі рядки
s
замінник
g
замінити всі екземпляри у кожному рядку
x
написати, якщо зміни були внесені (вони були) та вийти
Через команду 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",$1);}' file
Він замінює 1 на 0 лише в першому стовпці.
Через Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
inotifywait
програмою under sh
env та повідомляю про дані у форматі CSV (оскільки користувацький формат є помилковим). Потім я зрозумів, що немає простого способу обробки CSV-документа в скриптах оболонки ... І мені це дуже легко. Тому я запустив досить простий сценарій для розбору та повідомлення CSV. Я прочитав специфікацію CSV і помітив, що вона досконаліша, ніж я очікувала, і підтримую багаторядне значення, загорнуте у подвійні лапки. Я покладався на sed
токенізацію, але незабаром зрозумів, що навіть те, що sed
називати мультилініями, до двох ліній. Що робити, якщо одне з моїх значень CSV охоплює більше двох рядків?
sed
є s Tream ред itor , в тому , що ви можете використовувати |
(труби) для передачі стандартних потоків (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
параметр використовується для редагування i n місця у файлі hello.txt
.
-e
У цьому випадку опція вказує команду e xpression / команда для запуску 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, виконайте:
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"
де [tensorboard / program.py] - файл для пошуку
logdir', ''
-> /logdir', os.getcwd()
) робить цю відповідь важкою для розбору. Крім того, варто уточнити, що ваша відповідь спочатку знаходить файли для використання sed, оскільки це не є частиною питання.