Как найти и заменить строку без команды Sed использования?

Сценарий, который Вы отправили, преобразовывает 4*n пробелы в n вкладки, только если тем пробелам предшествуют только вкладки.

Если Вы хотите заменить 4 пробелов 2 пробелами, но только в добавлении отступа, в то время как возможно сделать это с sed, я рекомендую Perl вместо этого.

perl -pe 's{^((?: {4})*)}{" " x (2*length($1)/4)}e' file

В sed:

sed -e 's/^/~/' -e ': r' -e 's/^\( *\)~    /\1  ~/' -e 't r' -e 's/~//' file

Можно хотеть использовать indent вместо этого.

16
29.12.2015, 14:49
6 ответов

Да существует множество способов сделать это. Можно использовать awk, perl, или bash сделать эти операции также. В целом, хотя sed вероятно, больше всего кстати инструмент для того, чтобы сделать эти типы задач.

Примеры

Скажите, что у меня есть эти демонстрационные данные в файле data.txt:

foo bar 12,300.50
foo bar 2,300.50
abc xyz 1,22,300.50

awk

$ awk '{gsub("foo", "foofoofoo", $0); print}' data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Perl

$ perl -pe "s/foo/foofoofoo/g" data.txt 
foofoofoo bar 12,300.50
foofoofoo bar 2,300.50
abc xyz 1,22,300.50

Встроенное редактирование

Вышеупомянутые примеры могут непосредственно изменить файлы также. Пример Perl тривиален. Просто добавьте -i переключатель.

$ perl -pie "s/foo/foofoofoo/g" data.txt 

Для awk это является немного менее прямым, но столь же эффективным:

$ { rm data.txt && awk '{gsub("foo", "foofoofoo", $0); print}' > data.txt; } < data.txt

Этот метод создает подоболочку с фигурными скобками '{...}' Где файл перенаправляется в него через это:

$ { ... } < data.txt

После того как файл был перенаправлен в подоболочку, он удален и затем awk выполняется против содержания файла, который был считан в подоболочки STDIN. Это содержание затем обрабатывается awk и записанный обратно к тому же имени файла, которое мы просто удалили, эффективно заменив его.

12
27.01.2020, 19:48
  • 1
    Спасибо за Вас отвечают, и я попробую его затем рабочий день. Но я не уверен, работает ли это, потому что некоторая команда, возможно, не существует в обрезанном Linux системы ТВ, такой как, 'sed '.So я все еще хочу использовать команду, 'находят', 'grep' и так далее для решения его. –  binghenzq 25.10.2013, 18:47
  • 2
    @binghenzq - Я добавил примеры, которые встраивают, редактируют файл. –  slm♦ 02.11.2013, 18:28
  • 3
    1 я редко downvote, но в этом случае точка вопроса, казалось, был более простым методом, а не другим больше/одинаково комплекс и вероятно также зависимый. Если вопросом были примерно альтернативы для полного *, отклоняют установку машины затем, я был бы, вероятно, +1 этот в других отношениях хороший ответ. –  Michael Durrant 02.11.2013, 18:36
  • 4
    @MichaelDurrant - Я просто добавил те тщательно продуманные встроенные редактирования b/c OP, который попросили их. Также OP устанавливают требование не использования sed не я. Sed является соответствующим инструментом для того, чтобы сделать замены, такие как это, и он, очевидно, просит лучше понимать роли этих инструментов, таким образом показывая кому-то эти вещи, хотя плохо, чрезвычайно образование в показе их почему. Слишком много раз знающие люди просто заявляют, "не делают этого", не объясняя, почему, таким образом, я. Но спасибо за то, что, по крайней мере, оставили комментарий, относительно почему Вы DV. –  slm♦ 02.11.2013, 18:37
  • 5
    Несомненно, я думал, что это был большой ответ во всех других отношениях. да я ненавижу-1 без объяснения. –  Michael Durrant 02.11.2013, 18:41

Классическая альтернатива для однобуквенных замен tr команда, которая должна быть доступной в примерно любой системе:

$ echo "foobar" | tr a b   
foobbr

tr лучше, чем sed для этого на самом деле начиная с использования sed (уже не говоря о perl или awk) поскольку однобуквенные замены похожи на использование молотка саней для уничтожения мухи.

grep не разработан для этого, это не изменяет свой вход, это только перерывает его.

С другой стороны, можно использовать возможности замены некоторых оболочек. Сюда использование ksh, zsh или bash синтаксис:

$ foo="foobar"
$ echo "${foo//a/b}"
foobbr

Мы могли дать Вам более определенные ответы, если бы Вы объяснили точно, какую проблему Вы пытаетесь решить.

13
27.01.2020, 19:48
  • 1
    эха Являются там опцией игнорировать регистр в ${foo//a/b}? –  AlikElzin-kilaka 23.02.2017, 09:19
  • 2
    @AlikElzin-kilaka я боюсь нет. Необходимо будет использовать что-то более сложное как, например: echo "$foo" | sed 's/a/b/i или дайте класс символов: echo ${foo//[aA]/b}. –  terdon♦ 23.02.2017, 12:03

Если Вы работаете с файлом, а не потоком, Вы могли бы использовать стандартный текстовый редактор, ed:

printf '%s\n' ',s/a/b/g' w q | ed file.txt

Это должно быть доступно на любом *, отклоняют. Запятая в ',s/a/b/g' говорит ed работать над каждой строкой (можно также использовать %, который будет более знакомым, если Вы привыкнете к энергии), и остальная часть ее является стандартным поиском и заменой. w говорит, что это для записи (сохранило) файл, q говорит этому выходить.

Отметьте это, в отличие от sed's -i опция (и подобные опции в других инструментах), это на самом деле редактирует файл, оперативный вместо того, чтобы обмануть с временными файлами.

Я не думаю, что возможно получить эту работу с потоками, но затем я действительно не знаю много о ed и я не был бы удивлен, имеет ли это на самом деле ту возможность (философия Unix, являющаяся, что это).

3
27.01.2020, 19:48

Используя команду предка (в который -s средства, тихие (тихий) и запятая перед средствами команд, выполняются на всех строках):

Просто печать на STDOUT:

ed -s file <<!
,s/a/b/g
,p
q
!

оперативная замена:

ed -s file <<!
,s/a/b/g
w
q
!
2
27.01.2020, 19:48

Вы можете использовать Vim в режиме Ex:

ex -s -c '%s/a/b/g|x' file
  1. % выбрать все строки

  2. s заменить

  3. g глобальную замену

  4. x сохранить и закрыть

4
27.01.2020, 19:48

Если вы используете ОС Linux, например, Ubuntu Desktop, как и я, у вас будет установлен python.

С помощью Python мы можем заменить текст, как показано ниже

result=$(python << EOT
s = '$your_string_in_shell_script'
r = s.replace('text to replace', 'replaced by this text')
print(r)
EOT)

echo $result
0
22.09.2021, 16:40

Теги

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