Перед запуском протестуйте рекурсивний пошук sed та замініть його


13

Чи є спосіб запустити пробний рекурсивний пошук і замінити його sed, перш ніж його реально запустити? Я просто хочу роздрукувати результати, перш ніж насправді здійснити пошук та заміну. Щось на зразок повторення результатів,

grep -rl term1 . |xargs sed -i -e 's/term1/term2/'

Зробіть копію даних, запустіть свою команду, огляньте результат.
Кусалаланда

Відповіді:


10

Ви можете бігти sedбез -iі переходити через вихідless

grep -rl --null term1 . | xargs -0 sed -e 's/term1/term2/' | less

Потім запустіть sedз -i.bakдля створення резервних копій , які ви можете Diff згодом

grep -rl --null term1 . | xargs -0 sed -i.bak -e 's/term1/term2/'
diff somefile.bak somefile
# verify changes were correct

Редагувати: Як запропоновано в коментарі, використовуйте grep --null | xargs -0. Це призводить до припинення назви файлів нульовим байтом, що робить його безпечним для імен файлів з незвичайними символами, такими як новий рядок. Так, \nє дійсним символом в імені файлу unix. Єдиними забороненими символами є нахил /та нульовий символ\0


Цікаво, що я спробував знайти значення -i, але воно не було вказане під man sed. Ваше рішення спрацювало. Що було б найкращим, на вашу думку, просто перерахувати рядки, а не весь файл? Замість того, щоб прокладати менше, я трубопровід | grep term2, який працював, але я отримав певний вихід із дивними символами.
користувач251482

@ user251482 - "Просто перерахуйте рядки", як у "перегляді різниці між старим та новим файлом"?
grebneke

1
@StephaneChazelas Так, а ще краще, grep -rl --nullоскільки OP не вказав ОС, а -Zозначає BSD / OSX (розпакувати) щось інше. --nullте саме і для GNU, і для BSD
grebneke

1
@grebneke. Добре, але зауважте, що ОП використовує синтаксис GNU sed, тому ми можемо припустити, що він не на BSD. Зверніть увагу, що grepце (вилка) GNU grep на FreeBSD та NetBSD. У NetBSD -Zвсе ще означає --null(згідно зі сторінкою man), але я згоден - unul є більш портативним. Також зауважте, що ані - не працює, ані -Z працює над OpenBSD
Stéphane Chazelas

1
@grebneke, це sed -i '' -e s/.../в BSD sed(додаткові опції немає)
Stéphane Chazelas

5

Використовуйте за sedдопомогою, findа неgrep

Перш за все, я б працював, findа не це grep, і це з трьох вагомих причин:

  1. findдозволяє більш точний вибір файлу. Наприклад, grep -r string *.txtбуде видаватися файли лише в поточному каталозі; не ті, що у підкаталогах.
  2. findпоставляється з потужним -execваріантом, який виключає потребу в цілому --null … |xargs 0конструкції.
  3. Параметри -readableта -writableпараметри findне дозволять витрачати час на файли, до яких не можна отримати доступ.

Тест на захоплення

Однак, grepчи не піддається першому тестуванню, щоб побачити, що було б захоплено:

$ find . -exec grep term1 {} \;

або більш конкретно:

$ find . -type f -name '*.txt' -readable -writable -exec grep term1 {} \;

Сухий біг

Тепер приступайте до sedсухого ходу. sedВаріантом -nє синонімом --quietі pв самому кінці sedвиразу надрукує поточний простір картини.

$ find . -exec sed -n 's/term1/term2/gp' {} \;

або більш конкретно:

$ find . -type f -name '*.txt' -readable -writable -exec sed -n 's/term1/term2/gp' {} \;

Виконання

Якщо все виглядає нормально, видає остаточну команду, замінивши sedопцію -nна -iдля «на місці» і видалення pв кінці.

$ find . -exec sed -i 's/term1/term2/g' {} \;

або більш конкретно:

$ find . -type f -name '*.txt' -readable -writable -exec sed -i 's/term1/term2/g' {} \;

Більше findприкладів

Більше findприкладів можна знайти тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.