用 sed 引用特殊字符 [英] Quoting special characters with sed

查看:63
本文介绍了用 sed 引用特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试查看传递给我的程序的变量(变量为 $1)并用所述特殊字符的引用形式替换任何特殊字符,以免特殊字符实际执行它通常会做的事情.

I'm trying to look in a variable passed to my program (the variable is $1) and to replace any special characters with quoted forms of said special character, in order to not have the special character actually do what it normally would.

我的代码是

#!/bin/sh
target="$1"
newtarget=`echo "$target" | sed -e s/\*/\\*/g`
newtarget=`echo "$newtarget" | sed -e s/\^/\\^/g`
newtarget=`echo "$newtarget" | sed -e s/\+/\\+/g`
newtarget=`echo "$newtarget" | sed -e s/\-/\\-/g`
newtarget=`echo "$newtarget" | sed -e s/\\/\\\/g`
newtarget=`echo "$newtarget" | sed -e s/\./\\./g`
newtarget=`echo "$newtarget" | sed -e s/\$/\\$/g`
newtarget=`echo "$newtarget" | sed -e s/\[/\\[/g`
newtarget=`echo "$newtarget" | sed -e s/\]/\\]/g`
sed s/"$newtarget"/"$2"/g "$3" > "$3.updated"
mv "$3.updated" $3

我的第一行 $target 应该查看目标字符串并查看字符串中是否有 *.如果有,它将用 * 替换它.在代码中,它显示为 * 然后显示为 \* 的原因是程序看不到 * 并认为它想要实际使用 *,它只是通过用 引用它来将 * 视为常规字符.我在所有其他行中都做了同样的事情,但使用了不同的字符.在第一个之后,它应该检查 newtarget 并执行相同的操作,但具有不同的字符.

My first line, with $target, should look in the target string and see if there's a * in the string. If there is, it will replace it with *. The reason that in the code, it appears as * and then \*, is so that the program doesn't see * and think it wants to actually use *, it just sees * as a regular character by quoting it with . I've done the same thing in all of the other lines, but with different characters. After the first one, it should check in newtarget and do the same thing, but with different characters.

我的整个程序应该做的是,它传递了3个参数,第一个是要替换的字符串,第二个是要替换的字符串,第三个是文件名.所以到最后,如果文件最初是这样的

What my overall program should do, is that it's passed 3 parameters, the first is a string to be replaced, the second is a string to replace it, and the third is a filename. So by the end of it, if the file was originally something like

aa\^a*aa$aa[aaa$a]a 

我提供

"a\^a*" "test"

作为参数,结果应该是

atestaa$aa[aaa$a]a 

但是我的代码仍然不起作用.我的代码有什么问题?我不知道我的 sed 语法是否适合编码,或者我的附加语句是否不起作用,或者我是否必须对某些特殊字符进行特殊引用.

But my code still doesn't work. What's wrong with my code? I don't know if my sed syntax is right with coding, or if my additional statements don't work, or if I have to special quoting for some of the special characters.

我知道我应该能够像我一样使用多个 sed 命令来做到这一点,但我不知道为什么它们不能正常工作,所以我很确定这与我的引用有关在newtarget="行末尾的实际 sed 命令中.

I know that I should be able to do this with multiple sed commands like I have, but I don't know why they aren't working right, so I'm pretty sure it's something to do with my quoting in the actual sed commands at the end of the "newtarget=" lines.

我现在在我的代码中引用了我的 sed 参数,但它仍然无法正常工作.我需要引用某些特殊字符的特殊方法吗?我认为在每个字符前加一个反斜杠会正确引用它.

I have quoted my sed arguments in my code now, but it's still not working properly. Are there special ways I need to quote certain special characters? I assumed that putting a backslash in front of each character would properly quote it.

#!/bin/sh
target="$1"
newtarget=`echo "$target" | sed -e 's/\*/\\*/g'`
newtarget=`echo "$newtarget" | sed -e 's/\^/\\^/g'`
newtarget=`echo "$newtarget" | sed -e 's/\+/\\+/g'`
newtarget=`echo "$newtarget" | sed -e 's/\-/\\-/g'`
newtarget=`echo "$newtarget" | sed -e 's/\\/\\\/g'`
newtarget=`echo "$newtarget" | sed -e 's/\./\\./g'`
newtarget=`echo "$newtarget" | sed -e 's/\$/\\$/g'`
newtarget=`echo "$newtarget" | sed -e 's/\[/\\[/g'`
newtarget=`echo "$newtarget" | sed -e 's/\]/\\]/g'`
sed s/"$newtarget"/"$2"/g "$3" > "$3.updated"
mv "$3.updated" $3

推荐答案

多次调用 sed 的目的是在每次出现一组字符之前放置一个文字反斜杠.这可以在一次调用 sed 中完成,但您需要注意如何指定集合.

The purpose of the multiple invocations of sed is to place a literal backsplash before each occurrence of a set of characters. This can be done in one call to sed, but you need to be careful about how you specify the set.

首先,让我们看看一般命令的样子:

First, let's see what the general command will look like:

newtarget=$( echo "$target" | sed -e 's/\([...]\)/\\\1/g'

其中 ... 将替换为要转义的字符集.此命令使用括号来捕获这些字符之一的单个实例,并将其替换为反斜杠,后跟捕获的字符.要指定字符集,请使用

where ... will be replaced with the set of characters to escape. This commands uses parentheses to capture a single instance of one of those characters, the replaces it with a backsplash followed by the captured character. To specify the set of characters, use

[]*^+\.$[-]

两个注意事项:首先,] 必须在前,以免误认为是集合的结尾,因为 [] 是无效集合.其次,- 必须放在最后,以免被误认为是范围运算符(例如,[az] 是小写字母的集合,但 [z-] 只是三个字符 az-).

Two notes: first, the ] must come first so that it isn't mistaken for the end of the set, since [] is an invalid set. Second, - must come last, so that it isn't mistaken as the range operator (e.g., [a-z] is the set of lowercase letters, but [az-] is simply the three characters a, z, and -).

综合起来:

 newtarget=$( echo "$target" | sed -e 's/\([]*^+\.$[-]\)/\\\1/g' )

这篇关于用 sed 引用特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆