我正在从日志中打印一些监控数据,如下所示:
printf " %10s %5s %25s %15s %15s %s${txtrst}\n" $date $time $metric $status $current_criticality "$failure"
我想要最后一列,它没有定义的长度来在其边界内换行,其中左侧是明确定义的,右侧是屏幕所在的位置(正常换行位置)。我试图定义长度,但这并没有解决它。
电流输出示例:
09/30/2015 14:39 execution (SUCCESS) SUCCESS
09/30/2015 14:34 execution (FAILED) ERROR Step 3: Match Failed Blah blah blah blah blah blah blah.
09/30/2015 14:34 execution (FAILED) SUCCESS Step 1: Match Failed Blah blah blah blah blah blah blah.
09/30/2015 14:34 round_trip (10.174) ERROR Step 1: Match Failed Blah blah blah blah blah blah blah.
09/30/2015 14:34 round_trip (10.174) SUCCESS Step 1: Match Failed Blah blah blah blah blah blah blah.
09/30/2015 13:30 round_trip (94.652) ERROR
09/30/2015 13:30 round_trip (94.652) SUCCESS
09/30/2015 13:19 round_trip (0.257) SUCCESS
09/30/2015 13:16 round_trip (110.012) ERROR
09/30/2015 13:16 round_trip (110.012) SUCCESS
我愿意去看:
09/30/2015 14:39 execution (SUCCESS) SUCCESS
09/30/2015 14:34 execution (FAILED) ERROR Step 3: Match Failed
Blah blah blah blah
blah blah blah.
09/30/2015 14:34 execution (FAILED) SUCCESS Step 1: Match Failed
Blah blah blah blah
blah blah blah.
09/30/2015 14:34 round_trip (10.174) ERROR Step 1: Match Failed
Blah blah blah blah
blah blah blah.
09/30/2015 14:34 round_trip (10.174) SUCCESS Step 1: Match Failed
Blah blah blah blah
blah blah blah.
09/30/2015 13:30 round_trip (94.652) ERROR
09/30/2015 13:30 round_trip (94.652) SUCCESS
09/30/2015 13:19 round_trip (0.257) SUCCESS
09/30/2015 13:16 round_trip (110.012) ERROR
09/30/2015 13:16 round_trip (110.012) SUCCESS
很像 SQL*PLUS 的列格式报告: col $column format a15
预先感谢您的任何想法!
答案1
这是一个仅能起作用的克鲁格,因为它是最后一列:
printf
该行的第一部分(除 之外的所有部分$failure
,包括间距),没有尾随的新行。echo "$failure" | fold -s -w $desired_width | sed -e "2,\$s/^/$spacing/"
其中$desired_width
是列的宽度$failure
, $spacing 是使第二行(第三行等)在正确位置开始的大量空格。您可以使用类似的东西轻松生成这些空间spacing=$(echo $'\t' | pr -Te71)
。如果我没数错的话,71应该可以...
这是通过fold
执行换行,然后sed
向第二列和后续列添加间距(用于对齐)来实现的。打印时,第一行将与其他输出连接(由于缺少换行符)。
如果我想以正确的方式做到这一点,Perl 有几个模块(例如,Text::ASCIITable
,Text::SimpleTable
,Text::TabularDisplay
应该能够做到这一点。
答案2
可能有些东西已经存在了,但是......
awk -v cols=$(tput cols) '
NR == 1 {
prefix = gensub(/^(([[:blank:]]*[^[:blank:]]+){5}).*/, "\\\\1", 1, $0)
prefix_width = length(prefix) + 2
diff = cols - prefix_width
}
NF == 5 { print; next }
{
prefix = substr($0, 0, prefix_width)
text = substr($0, prefix_width+1)
while (length(text) > diff) {
for (i=diff; i>0; i--) {
char = substr(text,i,1)
if (char == " " || char == "-") break
}
if (i == 0) i = diff # no spaces or hyphens, break mid-word
printf "%*s%s\n", prefix_width, prefix, substr(text,0,i);
text = substr(text,i+1)
prefix = ""
}
if (text) printf "%*s%s\n", prefix_width, prefix, text
}
' file
答案3
粗略的方法是重新格式化后
indent=' '
sed "s/.\{$((${#indent}+2)),$COLUMNS\} /&\n$indent /;P;D"
(其中indent
70 个空格 == 10 + 5 + 25 + 15 + 15 来自printf
命令)
但是预格式化更好:
indent=' '
mapfile failure < <(fold -s -w $(($COLUMNS-${#indent}-1)) <<<"$failure")
printf "%10s%5s%25s%15s%15s" $date $time $metric $status $current_criticality
printf " %b$indent" "${failure[@]}\c"