我在 unix 中使用 sed 替换文件中带有特殊字符的文本。我在 Google 上搜索并找到了以下命令
sed 's/from/to/g' file.txt
这里的“from”是被替换的原始文本,“to”是被替换的文本
我试图将其应用于包含特殊字符的长文本的文件,即将“/D/dec/prog/g++.exe -Wall --std=c++0x”(不带引号)替换为“SYSTEM_PATH/BIN”,我尝试了以下操作,但不起作用
sed 's//D/dec/prog/g++.exe -Wall --std=c++0x/SYSTEM_PATH/BIN/g' file.txt
但这会出现错误“sed:-e 表达式#1,字符 10:未知选项‘s’”。
我是 unix 的初学者,但出于某种原因,我需要远程登录 unix 服务器来处理一些文件。我想知道
1)如何将来自和到字符串定义为变量,例如 FROMSTR = '/D/dec/prog/g++.exe -Wall --std=c++0x' TOSTR = 'SYSTEM_PATH/BIN'
所以我可以像 sed 's/$FROMSTR/$TO/g' file.txt 一样调用 sed
但似乎 sed 不知道如何将其解释为变量
2) 用 sed 替换文本后,它不会将结果写回到原始文件。如何让它工作?
答案1
替代命令不需要用作/
分隔符。
sed 's!/D/dec/prog/g++.exe -Wall --std=c++0x!SYSTEM_PATH/BIN!g' file.txt
答案2
按照问题中的说明进行操作:首先设置您拥有的内容以及将用什么来替换它:
(base) localhost:~ # FROMSTR='/D/dec/prog/g++.exe -Wall --std=c++0x'
(base) localhost:~ # echo $FROMSTR
/D/dec/prog/g++.exe -Wall --std=c++0x
(base) localhost:~ # TOSTR='SYSTEM_PATH/BIN'
(base) localhost:~ # echo $TOSTR
SYSTEM_PATH/BIN
然后创建一个文件来运行 sed。
(base) localhost:~ # cat > testSED
1/D/dec/prog/g++.exe -Wall --std=c++0x1
2/D/dec/prog/g++.exe -Wall --std=c++0x2/D/dec/prog/g++.exe -Wall --std=c++0x2
3/D/dec/prog/g++.exe -Wall --std=c++0x3
然后运行 sed 调用变量,但是对于第一个变量,我们需要使用 echo:
(base) localhost:~ # sed -e "s|`echo $FROMSTR`|$TOSTR|" testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2/D/dec/prog/g++.exe -Wall --std=c++0x2
3SYSTEM_PATH/BIN3
(base) localhost:~ # sed -e "s|$FROMSTR|$TOSTR|g" testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3
要实现这个功能,需要做以下几点:
- 将我们习惯的 sed 分隔符 / 替换为 |,或者替换为两个变量中未使用的内容。
- 如果使用单引号 ',则变量将被读取为其名称而不是其内容。$TOSTR 将是 $TOSTR 而不是 SYSTEM_PATH/BIN。
- 使用双引号才能解释变量。
如果您想让 sed 使用替换来重写文件,那么您必须在 sed 选项中添加 -i,但建议使用 > 将输出重定向到新文件。
(base) localhost:~ # sed "s|$FROMSTR|$TOSTR|g" testSED > testSEDdone
(base) localhost:~ # cat testSEDdone
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3
(base) localhost:~ # cat testSED
1/D/dec/prog/g++.exe -Wall --std=c++0x1
2/D/dec/prog/g++.exe -Wall --std=c++0x2/D/dec/prog/g++.exe -Wall --std=c++0x2
3/D/dec/prog/g++.exe -Wall --std=c++0x3
(base) localhost:~ # sed -i "s|$FROMSTR|$TOSTR|g" testSED
(base) localhost:~ # cat testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3