如何将named.conf的区域块重新格式化为单行?

如何将named.conf的区域块重新格式化为单行?

由于我不会在这里详细讨论的原因,我需要复制旧的 CentOS 5.10 服务器的 name.conf 文件,并在副本上执行一些文本操作。最终结果应该将每个区域的信息合并到一个单独的行中。另外,我需要编写它的脚本,以便它可以作为 cron 作业运行。这是我开始的一个例子:

区“.” {
        类型提示;
        文件“named.root”;
};

区域“somedomain.com”{
        类型大师;
        文件“somedomain.net”;
        允许传输{
                11.11.11.11;
                22.22.22.22;
                共同允许转移;
        };
};

区域“otherdomain.com”{
        类型大师;
        文件“otherdomain.com”;
        允许传输{
                33.33.33.33;
                44.44.44.44;
                55.55.55.55;
                共同允许转移;
        };
};

以下是编辑后的文件中应显示的内容的示例:

区“.” { 输入提示;文件“named.root”; };
区域“somedomain.com”{类型master;文件“somedomain.net”;允许传输{ 11.11.11.11; 22.22.22.22;共同允许转移; }; };
区域“otherdomain.com”{类型master;文件“otherdomain.com”;允许传输 { 33.33.33.33; 44.44.44.44; 55.55.55.55;共同允许转移; }; };

我和我的 CIO 未能成功地搜索到将 name.conf 转换为每区域一行格式的现有脚本。使用 tr 和 sed,我成功地 1)将所有制表符转换为空格,2)将多个连续空格压缩为单个空格。结果更接近我所需要的,但我仍然无法删除不需要的换行符,同时保留所需的换行符。这是接近正确的示例输出:

区“.” {
 类型提示;
 文件“named.root”;
};
区域“somedomain.com”{
 类型大师;
 文件“somedomain.net”;
 允许传输{
 11.11.11.11;
 22.22.22.22;
 共同允许转移;
 };
};
区域“otherdomain.com”{
 类型大师;
 文件“otherdomain.com”;
 允许传输{
 33.33.33.33;
 44.44.44.44;
 55.55.55.55;
 共同允许转移;
 };
};

测试了一些建议的 sed、awk 和 tr 表达式来解决换行问题,但没有一个表达式给出所需的输出。您提出的任何建议——甚至是像“用 sed 和 x,y,z 进行实验”这样的一般方向——将不胜感激。谢谢!

答案1

在 Vim(或直接)中打开文件vi并输入:

:g/^zone/.,/^}/j

瞧,你完成了。


这在g全局运行,在以 开头的每一行zone,命令:

.,/^}/j

这意味着,从当前行 ( .) 到以右大括号开头的下一行,j将所有这些行放在一起。


如果您需要编写脚本,请使用vi的脚本形式ex

printf '%s\n' 'g/^zone/.,/^}/j' x | ex file.txt

答案2

尝试这个:

sed -n '
    /^zone/,/^};/ H          # append current line to hold space in this range
    /^};/ {                  # at the end of the range:
        s/.*//               #   erase the current line
        x                    #   exchange pattern space with hold space
        s/\n//               #   remove first newline (before "zone")
        s/[[:space:]]\+/ /g  #   condense all other whitespace including newlines
        p                    #   and print this zone record
    }
' named.conf 

结果

zone "." { type hint; file "named.root"; };
zone "somedomain.com" { type master; file "somedomain.net"; allow-transfer { 11.11.11.11; 22.22.22.22; common-allow-transfer; }; };
zone "otherdomain.com" { type master; file "otherdomain.com"; allow-transfer { 33.33.33.33; 44.44.44.44; 55.55.55.55; common-allow-transfer; }; };

答案3

sed -e ':nextline' -e N -e 's/\n\s*\([^z]\)/\1/' -e 'tnextline' named.conf

答案4

您可以使用paragraph-modeofawk和工具以及该工具的Perl范围运算符来完成此操作:,sed

sed -e '
    /^zone/,/^$/!d
    H;/^zone/h;/^$/!{$!d;}
    g;s/[[:space:]]\{1,\}/ /g
    s/ $//
' input.file

awk -vRS= '{$1=$1}1' input.file

perl -pl -00e 's/\s+/ /g' input.file

perl -pl -00e 'tr/\t\040\n/ /s' input.file

输出:

zone "." { type hint; file "named.root"; };
zone "somedomain.com" { type master; file "somedomain.net"; allow-transfer { 11.11.11.11; 22.22.22.22; common-allow-transfer; }; };
zone "otherdomain.com" { type master; file "otherdomain.com"; allow-transfer { 33.33.33.33; 44.44.44.44; 55.55.55.55; common-allow-transfer; }; };

相关内容