sed正则表达式正在替换整个文件

时间:2014-11-13 07:15:06

标签: regex bash shell sed

我有hdfs-site.xml个文件,其中包含以下信息

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.name.dir</name>
        <value>/data/dfs/nn</value>
    </property>
    <property>
        <name>dfs.data.dir</name>
        <value>/data/dfs/dn,/mnt_test_volume/data/dfs/dn,/mnt_test_volume/data/dfs/dni,/mnt_test_v5olume/data/dfs/dn,/mnt_test_volume/d5ata/dfs/dgn</value>
    </property>
    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
</configuration>

我想删除<name>dfs.data.dir</name><value></value></name>标记中的一些条目。要删除的条目由shell脚本的一个参数决定。

我是sed的新手,我编写了以下sed命令来查找特定条目并将其删除。当第一次执行sed但下次执行相同命令时,这将按预期工作,文件的所有内容都将被清除,文件将变为空白文件。

sed -ni '1h; 1!H; ${g; s#\(<name>dfs\.data\.dir<\/name>[^a-zA-Z0-9]*<value>.*\)'$data_dir_path'[^,<]\(.*<\/value>\)#\1\2# p}' hdfs-site.xml

在此命令中$data_dir_path变量决定要删除的条目。

例如,如果data_dir_path的值为/mnt_test_volume/data/dfs/dn,那么我期待以下输出

<name>dfs.data.dir</name>          <value>/data/dfs/dn,,/mnt_test_volume/data/dfs/dni,/mnt_test_v5olume/data/dfs/dn,/mnt_test_volume/d5ata/dfs/dgn</value>

在执行一次命令时工作正常,但如果下次执行相同的命令,整个文件将变为空。

任何人都可以告诉我,我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

您可以使用更简单的sed作为

  sed "/<name>dfs.data.dir<\/name>/ {n; s#$data_dir_path##}" hdfs-site.xml

它的作用是什么?

  • -i现场编辑文件

  • '/<name>dfs.data.dir<\/name>/检查该行是否与模式匹配。如果是,则执行以下命令。请注意,以下命令在{}中分组为{n; s/'$data_dir_path'//}'

  • n;从文件中读取下一行到模式空间

  • s/'$data_dir_path'//替换$data_dir_path中带有null

  • 的值

<强>测试

$  sed "/<name>dfs.data.dir<\/name>/ {n; s#$data_dir_path##}" test

bash-3.2$ cat test
:
:
:
        <name>dfs.data.dir</name>
        <value>/data/dfs/dn,,i,/mnt_test_v5olume/data/dfs/dn,/mnt_test_volume/d5ata/dfs/dgn</value>
:
:
: