由于我不会在这里详细讨论的原因,我需要复制旧的 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-mode
ofawk
和工具以及该工具的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; }; };