在 Linux 的命令行中,有哪些方法可以将固定字符串(非正则表达式)替换为整个单词?

在 Linux 的命令行中,有哪些方法可以将固定字符串(非正则表达式)替换为整个单词?

在 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

答案4

命令是:

perl -p0e 's/\b\Qb.*c\E\b/\\t/g' file.txt

$ cat file.txt
1. abcd
2. a b c d
3. ab.*cd
4. ab.*c d
5. a b.*c d

$ perl -p0e 's/\b\Qb.*c\E\b/\\t/g' file.txt
1. abcd
2. a b c d
3. ab.*cd
4. ab.*c d
5. a \t d

谢谢托托格伦·杰克曼, 和珍珠岩quotemeta文档

相关内容