Как сообщить о “sed” оперативных изменениях

Из того, что я видел, причины этого:

  • Миграция справки в главных версиях пакетов: когда PHP 5 был выпущен, возможно, один должен был иметь установку PHP 4. Это позволяет иметь выбор между версиями (по крайней мере, пока более старая версия не является устаревшей).

  • Продолжайте обеспечивать обновления более старой версии программного обеспечения (например, после того, как Apache 3 выпущен, мог бы быть необходим для исправления Apache 2), не обновляя его до более новой главной версии.

Например, ядро Linux имеет (с сегодняшнего дня) стабильные версии 3.5, 3.4.7, 3.2.24, 2.6.35.13 и т.д.... Если Вы работаете 2.6.35 в системе, и Вы хотите усовершенствовать ее, но не обновить это ядро, можно установить соответствующий пакет.

24
23.10.2013, 20:48
5 ответов

Вы могли использовать SED W Флаг с либо / dev / STDERR , / dev / tty , / dev / fd / 2 Если поддерживается в вашей системе. Например. С входом файл Как:

foo first
second: missing
third: foo
none here

Выполнение

sed -i '/foo/{
s//bar/g
w /dev/stdout
}' file

Выходы

bar first
third: bar

, хотя файл Content был изменен на:

bar first
second: missing
third: bar
none here

так в вашем случае, работает:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
s//bar/g
w /dev/fd/2
}' {} \;

Отредактируют файлы на месте и вывода:


./file1:
bar stuff
more bar

./file2:

./file3:
bar first
third: bar

Вы также можете распечатать что-то вроде Оригинальная линия >>> Модифицированная строка , например:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
h
s//bar/g
H
x
s/\n/ >>> /
w /dev/fd/2
x
}' {} \;

редактирует файлы на месте и выводах:


./file1:
foo stuff >>> bar stuff
more foo >>> more bar

./file2:

./file3:
foo first >>> bar first
third: foo >>> third: bar
16
27.01.2020, 19:40

Вы могли сделать это в двух передачах с помощью pдействие rint с первичной обработкой с:

find . -type f | xargs sed --quiet 's/abc/def/gp'

где --quiet заставляет sed не показать каждую строку и p снабдите суффиксом показывает только строки, где замена соответствовала.

Это имеет ограничение, которое не покажет sed, какие файлы изменяются, который, конечно, мог быть зафиксирован с некоторой дополнительной сложностью.

17
27.01.2020, 19:40
  • 1
    Это не вполне делает то, что я хотел, так как Вам нужны две передачи, но я голосую, потому что я просто изучил эту p вещь, и это очень полезно. Особенно, если, поскольку Вы сказали, файлы были также распечатаны. Что-то как for x in `find . -type f`; do echo ///File $x: ; sed --quiet 's/abc/def/gp' $x; done –  ricab 23.10.2013, 21:34
  • 2
    @msw у меня есть многие sed выражение, я не хочу писать /gp для каждого. Как установить его глобально? –  alhelal 07.01.2018, 03:30

Я не думаю, что это возможно, но обходное решение могло бы быть должно использовать жемчуг вместо этого:

find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 

Это распечатает измененные строки к стандартной погрешности. Например:

$ cat foo
fooabcbar
$ find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 
foodefbar

Можно также сделать это немного более сложным, печатая номер строки, имя файла, исходную строку и измененную строку:

$ find . -type f | 
   xargs perl -i -ne '$was=$_; chomp($was);
                      s/abc/def/ && print STDERR "$ARGV($.): $was : $_"' 
./foo(1): fooabcbar : foodefbar
8
27.01.2020, 19:40
  • 1
    +1 можно также использовать $ARGV для названия файла, управляемого на. –  Joseph R. 23.10.2013, 21:38
  • 2
    @JosephR. положительная сторона, добавил. Странный –  terdon♦ 23.10.2013, 21:46
  • 3
    Спасибо, это, вероятно, полезно (не протестировал его самостоятельно). Я не выбираю, поскольку это не использует sed, таким образом, это точно не отвечает на вопрос. –  ricab 23.10.2013, 23:06
  • 4
    @ricab это прекрасно, Вы не должны принимать ответ, если он на самом деле не отвечает на Ваш вопрос. Примите во внимание хотя это для простых вещей как это, perlсинтаксис очень похож на sedи я не думаю, что Вы просите, на самом деле возможно с sed. –  terdon♦ 23.10.2013, 23:14

Можно использовать флаг w, который записывает текущий образец в файл. Таким образом, добавив его в команду подстановки, мы можем сообщить о последовательных заменах в файл и распечатать его после выполнения задания. Также мне нравится окрашивать замененную строку в цвет grep.

sed -i -e "s/From/To/gw /tmp/sed.done" file_name
grep --color -e "To" /tmp/sed.done

Обратите внимание, что между w и именем файла должно быть только одно место.

Это даже лучше, чем diff, так как diff может также показывать изменения, даже если они не были сделаны с помощью sed.

3
27.01.2020, 19:40

Мне нравится решение @terdon -perl подходит для этого.

Вот моя измененная версия,:

  • не будет пытаться изменить файлы, в которых нет совпадающей строки
  • создаст резервную копию предыдущей версии файлов, которые изменятся (создаст версию.bak)
  • выведет список всех измененных файлов/линий, и показать СТАРУЮ и НОВУЮ версии этой строки с отступом и снизу для легкого чтения

код

find /tmp/test -type f ! -name "*.bak" -exec grep -l '/opt/gridmon' {} \; | xargs -L1 perl -ni'.bak' -e'$old=$_; s/\/opt\/gridmon/~/g && print STDERR "$ARGV($.):\n\tOLD:$old\tNEW:$_"'

пример вывода

/tmp/test/test4.cfg(13):
    OLD:    ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
    NEW:    ENVFILE ~/server/etc/gridmonserver.cfg
/tmp/test/test4.cfg(24):
    OLD:    ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
    NEW:    ENVFILE ~/server/etc/gridmonserver.cfg
1
27.01.2020, 19:40

Теги

Похожие вопросы