Подтвердить что ты не робот

Sed или аналогичный: не интерпретировать как регулярное выражение, интерпретировать как фиксированную строку/литерал

Для grep существует фиксированная строка, -F (fgrep), чтобы отключить интерпретацию регулярного выражения строки поиска. Есть ли аналогичное средство для sed? Я ничего не мог найти в этом человеке. Рекомендация другого инструмента gnu/linux также будет прекрасной.

Я использую sed для функции поиска и замены: sed -i "s/abc/def/g"

4b9b3361

Ответ 1

Вы должны использовать replace вместо sed.

На странице man:

   The replace utility program changes strings in place in files or on the
   standard input.

   Invoke replace in one of the following ways:

       shell> replace from to [from to] ... -- file_name [file_name] ...
       shell> replace from to [from to] ... < file_name

   from represents a string to look for and to represents its replacement.
   There can be one or more pairs of strings.

Ответ 2

Вам нужно использовать sed? Если вы пишете bash script, вы можете сделать

#!/bin/bash
pattern='abc'
replace='def'
file=/path/to/file
tmpfile="${TMPDIR:-/tmp}/$( basename "$file" ).$$"
while read -r line
do
  echo ${line/$pattern/$replace}
done < "$file" > "$tmpfile" && mv "$tmpfile" "$file"

С более старой оболочкой Bourne (такой как ksh88 или POSIX sh) у вас может не быть такой классной структуры ${var/pattern/replace}, но у вас есть ${var#pattern} и ${var%pattern}, которые можно использовать для разделения строки вверх и затем соберите его. Если вам нужно это сделать, у вас будет намного больше кода, но это действительно не так уж плохо.

Если вы уже не в оболочке script, вы можете легко сделать параметры шаблона, замены и имени файла и просто вызвать это.:)

PS - структура ${TMPDIR: -/tmp} использует $TMPDIR, если она установлена ​​в вашей среде, или использует /tmp, если переменная не установлена. Мне нравится вставлять pid текущего процесса в конец имени файла в надежде, что он будет немного более уникальным. Вероятно, вы должны использовать mktemp или подобное в "реальном мире", но это нормально для быстрого примера, и двоичный файл mktemp не всегда доступен.

Ответ 3

Вариант 1) Escape regexp. Например. sed 's/\$0\.0/0/g' заменит все вхождения $0.0 на 0.

Вариант 2) Используйте perl -p -e в сочетании с quotemeta. Например. perl -p -e 's/\\./,/gi' заменит все вхождения . на ,.

Вы можете использовать опцию 2 в сценариях, подобных этому:

SEARCH="C++"
REPLACE="C#"
cat $FILELIST | perl -p -e "s/\\Q$SEARCH\\E/$REPLACE/g" > $NEWLIST

Ответ 4

Если вы не против Ruby или длинных строк, вы можете использовать это:

alias replace='ruby -e "File.write(ARGV[0], File.read(ARGV[0]).gsub(ARGV[1], ARGV[2]))"'

replace test3.txt abc def

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

Ответ 5

если вы не хотите скрывать свою строку,
вы можете достичь своей цели в 2 этапа:

fgrep строка (получение списка номеров), которую вы хотите заменить,
и затем используйте sed для замены этой строки.

например.

#/bin/sh
PATTERN='foo*[)*abc'    # we need it literal
LINENUMBER="$( fgrep -n "$PATTERN" "$FILE" | cut -d':' -f1 )"

NEWSTRING='my new string'
sed -i "${LINENUMBER}s/.*/$NEWSTRING/" "$FILE"