对于
grep
,有一个固定字符串选项 -F
(fgrep
) 用于关闭搜索字符串的正则表达式解释。
sed
有类似的设施吗?我在这个人身上找不到任何东西。推荐另一个 gnu/linux 工具也可以。
我使用
sed
进行查找和替换功能:sed -i "s/abc/def/g"
必须使用
sed
吗?如果您正在编写 bash 脚本,您可以这样做
#!/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 shell(例如 ksh88 或 POSIX sh),您可能没有那么酷的
${var/pattern/replace}
结构,但您确实有 ${var#pattern}
和 ${var%pattern}
,它们可用于拆分字符串然后重新组装它。如果您需要这样做,您需要编写更多代码 - 但这确实还不错。
如果您还没有使用 shell 脚本,您可以很容易地创建模式、替换和文件名参数,然后调用它。 :)
PS:如果您的环境中已设置,则
${TMPDIR:-/tmp}
结构使用 $TMPDIR
,如果未设置变量,则使用 /tmp。我喜欢将当前进程的 PID 粘贴在文件名的末尾,希望它会更加独特。您可能应该在“现实世界”中使用 mktemp
或类似的东西,但这对于一个简单的例子来说是可以的,并且 mktemp
二进制文件并不总是可用。
选项 1)转义正则表达式字符。例如。
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
如果您不想想逃离字符串,您可以通过两步达到您的目标:
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"
如果你不反对 Ruby 或长线,你可以使用这个:
alias replace='ruby -e "File.write(ARGV[0], File.read(ARGV[0]).gsub(ARGV[1]) { ARGV[2] })"'
replace test3.txt abc def
这会将整个文件加载到内存中,执行替换并将其保存回磁盘。可能不应该用于大量文件。
如果您可以将整个文件读入内存,则可以用两行 bash 代码来完成此操作。这是非常灵活的——如果需要,模式和替换可以包含换行符以进行跨行匹配。它还保留任何尾随换行符或缺少换行符,而带有
read
的简单循环则不会。
mapfile -d '' < file
printf '%s' "${MAPFILE//"$pat"/"$rep"}" > file
为了完整性,如果文件可以包含空字节(
\0
),我们需要扩展上面的内容,它就变成了
mapfile -d '' < <(cat file; printf '\0')
last=${MAPFILE[-1]}; unset "MAPFILE[-1]"
printf '%s\0' "${MAPFILE[@]//"$pat"/"$rep"}" > file
printf '%s' "${last//"$pat"/"$rep"}" >> file
perl -i.orig -pse 'while (($i = index($_,$s)) >= 0) { substr($_,$i,length($s), $r)}'--\
-s='$_REQUEST['\'old\'']' -r='$_REQUEST['\'new\'']' sample.txt
-i.orig
带备份的就地修改。 -p
默认情况下从输入文件打印行-s
启用命令行参数的基本解析-e
运行此脚本index($_,$s)
搜索 $s
字符串substr($_,$i,length($s), $r)
更换字符串while (($i = index($_,$s)) >= 0)
重复直到 --
perl 参数结束 -s='$_REQUEST['\'old\'']'
、-r='$_REQUEST['\'new\'']'
- 设置 $s
、$r
您仍然需要“转义”
'
字符,但其余的应该是直接的。
注意:这首先是对如何将特殊字符串传递给 sed 因此是
$_REQUEST['old']
字符串的回答,但是这个问题的表述更为恰当。
您应该使用
replace
而不是 sed
。
来自手册页:
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.