Sed или аналогичный: не интерпретировать как регулярное выражение, интерпретировать как фиксированную строку/литерал
Для grep
существует фиксированная строка, -F
(fgrep
), чтобы отключить интерпретацию регулярного выражения строки поиска.
Есть ли аналогичное средство для sed
? Я ничего не мог найти в этом человеке. Рекомендация другого инструмента gnu/linux также будет прекрасной.
Я использую sed
для функции поиска и замены: sed -i "s/abc/def/g"
Ответы
Ответ 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"