На місці редагування з sed на OS X


142

Я хотів би відредагувати файл з sed на OS X. Я використовую таку команду:

sed 's/oldword/newword/' file.txt

Вихід відправляється в термінал. file.txt не змінено. Зміни зберігаються у file2.txt за допомогою цієї команди:

sed 's/oldword/newword/' file1.txt > file2.txt

Однак я не хочу іншого файлу. Я просто хочу відредагувати file1.txt . Як я можу це зробити?

Я спробував прапор -i. Це призводить до наступної помилки:

sed: 1: "file1.txt": invalid command code f

2
Яку саме команду ви використовуєте під час спроби -iпрапора?
eldarerathis

Відповіді:


282

Ви можете -iправильно використовувати прапор, надавши йому суфікс для додавання до резервного файлу. Розширення вашого прикладу:

sed -i.bu 's/oldword/newword/' file1.txt

Дасть вам два файли: один із ім'ям, file1.txtщо містить заміну, і один із ім'ям, file1.txt.buщо містить оригінальний вміст.

Легко небезпечний

Якщо ви хочете деструктивно перезаписати вихідний файл, використовуйте щось на кшталт:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

Через спосіб розбору рядка потрібен пробіл між прапором опції та його аргументом, оскільки аргумент дорівнює нулю.

За винятком можливої ​​руйнування вашого оригіналу, я не знаю жодної подальшої небезпеки обмацування sed таким чином. Слід зазначити, що якщо ця виклик sedє частиною сценарію, Unix Way ™ (IMHO) повинен використовувати sedнеруйнівно, перевірити, чи він вийшов чисто, і лише потім видалити сторонній файл.


Ти маєш рацію, я пропустив розширення після прапора -i. Є -i''небезпечним з будь-якої причини, крім потенційно зіпсувати вихідний файл (і не має РЕЗЕРВНИЙ)?
неділя, понеділок,

Згідно з sedдовідковою сторінкою, якщо у вас не вистачає місця на диску на пристрої, ви можете пошкодити файл із середини кроку та отримати поганий результат виводу. Якщо ви працюєте під контролем локального джерела sed -i ""без резервного копіювання, більшу частину часу (або безпосередньо git init && git add -A . && git commit -m 'backup'перед запуском sed в -iрежимі) слід добре працювати.
cfeduke

2
Мені небезпечний шматочок особливо корисний. +1
Андре

5
BSD sed вимагає, щоб після прапора -i не було місця. Отже, -i''діє, але -i ''ні.
Тодд А. Джейкобс

3
Арг! BSD sed ігнорує символ "\ n" і друкує "n" замість цього! Я просто збираюся замінити BSD sed на GNU sed на моєму комп'ютері!
nterry

20

У мене схожа проблема з MacOS

sed -i '' 's/oldword/newword/' file1.txt

не працює, але

sed -i"any_symbol" 's/oldword/newword/' file1.txt

працює добре.


Зараз це навпаки. sed -i '' <file>працює, але sed -i'' <file>більше не працює
Зохайб Аманзай


4

Ви можете використовувати -i''( --in-place) sedяк уже запропоновано. Див.: Аргумент -iна місці , проте зауважте, що -iопція - це нестандартні розширення FreeBSD і може бути недоступною для інших операційних систем. По-друге sed, це ідентифікатор S tream ED , а не редактор файлів .


Альтернативний спосіб - використовувати вбудовану підстановку в режимі Vim Ex, наприклад:

$ ex +%s/foo/bar/g -scwq file.txt

і для кількох файлів:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.*

Для редагування всіх файлів можна використовувати рекурсивно, **/*.*якщо оболонка підтримує це (увімкнути за допомогою shopt -s globstar).


Інший спосіб - це використання gawkта його нове розширення "inplace", таке як:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1

4

Це створює резервні файли. Наприклад, sed -i -e 's/hello/hello world/' testfileдля мене створюється файл резервного копіювання, testfile-e, в тому ж режимі.


Те саме тут і з Mac OS Catalina. При передачі обох -i та -e окремо (НЕ - разом!) Створюється резервний файл із доданим '-e'.
Даніель Кеснер

1

Ви можете використовувати:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

Приклад:

sed -i -e 's/Hello/Bye/' file.txt

Це працює бездоганно в Mac .


2
Це створює файл резервного копіювання для мене в Mac OS Catalina із доданим '-e'.
Даніель Кеснер

Це не так для macOS. Перегляньте сторінку "man sed" там. -iпотрібен аргумент для macOS. Оскільки ви не вказуєте одного, він використовує -e, що призводить до додавання другого файлу із -eдодаванням. -eне існує в macOS, це є -E. Тож правильною командою для macOS єsed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.