我一直在尝试创建一个脚本,将C:\
两种不同类型的文件中出现的每一个替换为/root
.
我的树状看起来像:
- Batch
- Place of the script
- Conf
- Appli1
- File1.xml
- File2.xml
- ...
- Appli2
- File1.xml
- File2.xml
- ...
- ...
- Info
- File1.conf
- File2.conf
- ...
我的脚本如下/Batch
:
#/bin/bash
find ../ -name "*.xml" -o name "*.conf" -print | xargs sed -i 's C:\ /root/ g'
但是,我有一个错误sed part
,它说在character 14: command 's' unfinished
为什么会这样?
答案1
您在哪里使用:
sed -i 's C:\ /root/ g'
你正在使用s
命令用空格字符分隔命令的不同部分,这是不寻常的,但完全有效。但是,当您在分隔符前面加上反斜杠时,它不会被视为分隔符,而是被视为参数本身的一部分。
您这里遇到的问题是,反斜杠C:\
正在逃逸中间的空格,因此s
永远找不到替换的结尾(现在是g
),并抱怨命令未完成,如您所见。
至少,您需要用另一个反斜杠转义反斜杠本身:
sed -i 's C:\\ /root/ g'
这将起作用,尽管用另一个字符替换空格可能会更清晰。
至于你的使用xargs
和子目录 -xargs
此处不需要,并且find
可以自己做到这一点,包括处理子目录中的文件。使用:
find ../ \( -name "*.xml" -o -name "*.conf" \) -exec sed -i -e 's|C:\\|/root/|g' '{}' +
运行find
命令sed
本身及其找到的所有文件名。插入文件名来代替{}
,+
意味着find
将最大限度地减少运行命令的次数。
-execdir
-exec
可能比中概述的某些安全原因更好find
手册页;它是一个非标准扩展,但由于您似乎正在使用 GNU 工具,因此如果您需要它,它应该就在那里。
答案2
这是反斜杠。反斜杠会消解下一个字符并使其失去特殊含义。 sed 命令正在读取您输入的内容(这里只是 sed 表达式,我不会执行整个繁琐的 shell 命令行):
s
<SPACE>
C
:
Literal <SPACE>
/root/
<SPACE>
您已经告诉 sed 您想要用作要查找的表达式及其替换的标记。但 sed 希望看到类似的内容:
s
<SPACE>
C
:
Literal \
<SPACE>
/root/
<SPACE>
要将反斜杠变成字面反斜杠,请在其前面添加一个反斜杠:
sed -e 's C:\\ /root '
就我个人而言,我宁愿避免使用空格。我会使用类似|
, 或 的东西;
。但反斜杠仍然存在问题。真正有趣的是计算出必须输入什么才能使用反斜杠作为分隔符。 :)