String sed帮助:基于下一行有条件地替换(美化ascii树输出)
我有一个程序,输出如下:String sed帮助:基于下一行有条件地替换(美化ascii树输出),string,awk,sed,String,Awk,Sed,我有一个程序,输出如下: 1405565344 | +- 1405722995 | | | +- 1405722998 | | | | | +- 1405724849 | | | +- 1406051621 | +- 1406051709 +- 1406733328 [END OF OUTPUT -- OUTPUT DOES NOT INCLUDE THIS LINE] 请注意,最后一行不是输出
1405565344
|
+- 1405722995
| |
| +- 1405722998
| | |
| | +- 1405724849
| |
| +- 1406051621
|
+- 1406051709
+- 1406733328
[END OF OUTPUT -- OUTPUT DOES NOT INCLUDE THIS LINE]
请注意,最后一行不是输出的一部分;如果我不在最后两行(大部分为空白)后面添加内容,那么最后两行将被隐藏。还要注意,在最后一个条目之后的空白行上有多个空格,但不显示它们。
所以我想把它做得更紧凑更好。。漂亮的使用以下sed
命令
sed -e 's,|,│,g' \
-e "s,+,└," \
-e "s,- ,─," \
-e '/^[ │]*$/d'
我可以将上述输入转换为:
1405565344
└─1405722995
│ └─1405722998
│ │ └─1405724849
│ └─1406051621
└─1406051709
└─1406733328
好多了。理想情况下,我希望是这样:
1405565344
├─1405722995
│ ├─1405722998
│ │ └─1405724849
│ └─1406051621
├─1406051709
└─1406733328
我知道差别很小,但它更有意义,并且更符合我程序的其他输出
所以基本上:我想要一种方法使sed
有条件地用+
替换+
└代码>或├代码>,取决于它后面的行。如果不采取完全不同的路线,似乎几乎是不可能的
有什么想法吗
sed -n -e '/| *$/ d;1h;1!H
$ {x
:a
s/\(\n[ |]*\)+\([^[:cntrl:]]*\1[|+]\)/\1├\2/;t a
:b
s/\(\n[ |]*\)+/\1└/;t b
s/|/│/g;s/- /─/g;p
}' YourFile
我应该做你的工作。使用图形字符以外的其他字符进行测试(不要在我的aix上传递)。
如果从一行的行首到下一行的行首(第一个新行之后的行首)的模式相同,则测试切换到T
。我使用[:cntrl:]捕捉非换行符,因此,如果有特殊字符被视为控制字符,它将失败(不要认为文件中有)。
如果不是,则角点处的情况(带+)更改de plus[为优化sed模式分组而修改][为角点字符而修改,以及具有相同模式的连续两行以+]结尾的情况]
我应该做你的工作。使用图形字符以外的其他字符进行测试(不要在我的aix上传递)。
如果从一行的行首到下一行的行首(第一个新行之后的行首)的模式相同,则测试切换到T
。我使用[:cntrl:]捕捉非换行符,因此,如果有特殊字符被视为控制字符,它将失败(不要认为文件中有)。
如果不是,则在角点处的情况(带有+)更改de plus的行[为优化sed模式分组而修改][为角点字符而修改,以及在相同模式下以+]结尾的两个连续行的情况下]我的逻辑是使用awk,|作为标记器,并使用$NF的长度来决定打印哪一行
cat <ip_file.txt> | awk -F'|' '{if(length($NF)>5)print $0;}'
注意:替换+-仍在等待中我的逻辑是使用awk、|作为标记器,并使用$NF的长度来决定打印哪一行
cat <ip_file.txt> | awk -F'|' '{if(length($NF)>5)print $0;}'
注意:更换+-仍在等待中Awk方式
可能会有很大的改进,但效果与预期一致。
我的机器无法显示├代码>或└
所以只要用它们替换#
和L
。
如果有人有任何改进,请告诉我,我会更新
awk '/\+/{a=$0;b=index($0,"+");next}
a{if(substr($0,b,1)=="|"){$0=gensub(/+/,"#","g",a)}else{$0=gensub(/+/,"L","g",a)}}
/[1-9]/{print $0}' file
输出
Awk方式
可能会有很大的改进,但效果与预期一致。
我的机器无法显示├代码>或└
所以只要用它们替换#
和L
。
如果有人有任何改进,请告诉我,我会更新
awk '/\+/{a=$0;b=index($0,"+");next}
a{if(substr($0,b,1)=="|"){$0=gensub(/+/,"#","g",a)}else{$0=gensub(/+/,"L","g",a)}}
/[1-9]/{print $0}' file
输出
这就行了。gawk的match()函数设置变量RSTART。我检查下一行以查看该位置的字符
gawk '
function g(line) {
gsub(/#/, "├", line)
gsub(/-/, "─", line)
gsub(/[+]/, "└", line)
gsub(/[|]/, "│", line)
return line
}
/^[[:blank:]|]*$/ {next}
prev {
while (match(prev, /[+]/)) {
c=substr($0, RSTART, 1);
if (c == "+" || c == "|")
sub(/[+]/, "#", prev)
else
break
}
print g(prev)
}
{prev=$0}
END {print g($0)}
' file
在行动中:
$ echo "1405565344
|
+- 1405722995
| |
| +- 1405722998
| | |
| | +- 1405724849
| |
| +- 1406051621
| +- foobar
|
+- 1406051709
+- barfoo" |
awk '
function g(line) {
gsub(/[+]/, "└", line)
gsub(/#/, "├", line)
gsub(/-/,"─", line)
gsub(/[|]/, "│", line)
return line
}
/^[[:blank:]|]*$/ {next}
prev {
while (match(prev, /[+]/)) {
c=substr($0, RSTART, 1);
if (c == "+" || c == "|")
sub(/[+]/, "#", prev)
else
break
}
print g(prev)
}
{prev=$0}
END {print g($0)}
'
这就行了。gawk的match()函数设置变量RSTART。我检查下一行以查看该位置的字符
gawk '
function g(line) {
gsub(/#/, "├", line)
gsub(/-/, "─", line)
gsub(/[+]/, "└", line)
gsub(/[|]/, "│", line)
return line
}
/^[[:blank:]|]*$/ {next}
prev {
while (match(prev, /[+]/)) {
c=substr($0, RSTART, 1);
if (c == "+" || c == "|")
sub(/[+]/, "#", prev)
else
break
}
print g(prev)
}
{prev=$0}
END {print g($0)}
' file
在行动中:
$ echo "1405565344
|
+- 1405722995
| |
| +- 1405722998
| | |
| | +- 1405724849
| |
| +- 1406051621
| +- foobar
|
+- 1406051709
+- barfoo" |
awk '
function g(line) {
gsub(/[+]/, "└", line)
gsub(/#/, "├", line)
gsub(/-/,"─", line)
gsub(/[|]/, "│", line)
return line
}
/^[[:blank:]|]*$/ {next}
prev {
while (match(prev, /[+]/)) {
c=substr($0, RSTART, 1);
if (c == "+" || c == "|")
sub(/[+]/, "#", prev)
else
break
}
print g(prev)
}
{prev=$0}
END {print g($0)}
'
IMHO,你已经超出了sed应该做什么的范围。Sed它真的很强大,并且具有hold string的概念,这可能会有所帮助。但它会给人一种难以管理的丑陋混乱:如果它太复杂,就使用python(resp perl,ruby,…)@SergeBallesta:这也是我的感觉;不过,我想我还是会问的。谢谢你的反馈。IMHO,你已经超出了sed应该做什么的范围。Sed它真的很强大,并且具有hold string的概念,这可能会有所帮助。但它会给人一种难以管理的丑陋混乱:如果它太复杂,就使用python(resp perl,ruby,…)@SergeBallesta:这也是我的感觉;不过,我想我还是会问的。谢谢你的反馈。非常好!我最初的想法是用awk
来做,但时间太晚了,我甚至没有尝试。我在学习你的代码。你做了最难的部分;现在我只需要将-
替换为─代码>和带有│代码>。非常好!我最初的想法是用awk
来做,但时间太晚了,我甚至没有尝试。我在学习你的代码。你做了最难的部分;现在我只需要将-
替换为─代码>和带有│
sed
太可笑了。。。但是哇,这太棒了@NeronLeVelu。就输出而言,只需一个简单的调整即可实现完美——将/\1L/
更改为/\1└/代码>。我说得太快了。你那惊人的代码并没有处理一些简单的情况,比如我刚刚添加到主帖子中的情况。你说得对,我忘记了这个情况,只是一个示例调优:-)(更改\1 |
后面的行:a by\1[|+]
(在回复中修改)sed
太可笑了……但是哇,这真是太棒了@NeronLeVelu。就输出而言,只需一个简单的调整,它就是完美的——将/\1L/
更改为/\1└/代码>。我说得太快了。你那惊人的代码不能处理一些简单的情况,比如我刚刚在主帖子中添加的情况。你是对的,我忘记了这个情况,只是一个示例调优:-)(更改\1 |
后面的行:a by\1[|+]
(在回复中修改)这是很酷的Raghuram——我使用awk
,我从来没有想过要这样做;但是,它并没有真正帮助解决我遇到的问题(因为我可以用一个简单的sed命令做那么多).这是很酷的Raghuram--我使用awk
,我从来没有想过这样做;但是,它并没有真正帮助解决我的问题(因为我可以用一个简单的sed命令做那么多)。太棒了,glenn!我喜欢