在 Linux 的命令行中,有哪些方法可以将固定字符串(非正则表达式)替换为整个单词?
例如,我想在 file.txt 中将文字“b.*c”作为一个整个单词替换为文字“\t”,而不转义任何字符:
1. abcd
2. a b c d
3. ab.*cd
4. ab.*c d
5. a b.*c d
预期结果:
1. abcd
2. a b c d
3. ab.*cd
4. ab.*c d
5. a \t d
答案1
一种没有明确转义特殊字符的 perl 方法,而是使用\Q
:
perl -ane 's/\Q b.*c /\t/;print' file.txt
1. abcd
2. ab.*cd
3. ab.*c d
4. a b c d
5. a d
答案2
你可以用 bash (版本 4+) 来做这件事,但它很麻烦
while IFS= read -r line; do
if [[ $line =~ (^|.*[^[:alnum:]])"b.*c"([^[:alnum:]].*|$) ]]; then
echo "${BASH_REMATCH[1]}\\t${BASH_REMATCH[2]}"
else
echo "$line"
fi
done < file.txt
在 bash 正则表达式中,引用的部分是文字。
如果您将模式保存在变量中,则不能只将变量放在引号中 - 这样正则表达式元字符将保留其特殊含义。不过,您可以强制转义每个字符。
pattern="b.*c
for ((i=0; i<${#pattern}; i++)); do escaped+="\\${pattern:i:1}"; done
然后使用
if [[ $line =~ (^|.*[^[:alnum:]])$escaped([^[:alnum:]].*|$) ]]; then
# ...............................^^^^^^^^.. unquoted
正如我所说,很粗糙。
答案3
您可以使用“sed”来搜索正则表达式替换。
sed -r 's/(\s)b\.\*c(\s)/\1\\t\2/g'
在某些版本的 sed 中,表达式必须在选项-e
. E 之前,在这种情况下-re
。
使用示例:
# source strings
sourceStrings="abcd\nab.*cd\nab.*c d\na b c d\na b.*c d"
pattern='s/(\s)b\.\*c(\s)/\1\\t\2/g'
# with `echo -e` for sh/bash, or `printf` for others shells
echo -e "$sourceStrings"| sed -r "$pattern"
# save string to file
printf "$sourceStrings" > file.txt
# replacing in content from file.txt with saving to another outputFile.txt
sed -r "$pattern" file.txt > outputFile.txt
# replacing in file
sed -ri "$pattern" file.txt