2015-03-14 3 views
1

мне нужно создать рамку вокруг вывода команды в терминале, так что если, например, вывод команды заключается в следующем:Создать рамку звездочки вокруг вывода в терминале?

Apple 
Paper Clip 
Water 

Станет это:

/==========\ 
|Apple  | 
|Paper Clip| 
|Water  | 
\==========/ 


Спасибо заранее за любые ответы.
-CL

+1

Является ли это ваша команда, или вы пытаетесь украсить вывод других команд? Пожалуйста, обновите свой вопрос, чтобы включить код, который вы уже пробовали, и объясните, какая часть его дает вам проблемы. –

+0

Я задал аналогичный вопрос некоторое время назад, что могло бы быть актуальным: http://stackoverflow.com/questions/22958873/make-echo-autofill-a-line-of-certain-width – Miguel

ответ

0

AWK кажется, наименее безумным способом идти об этом:

command | expand | awk 'length($0) > length(longest) { longest = $0 } { lines[NR] = $0 } END { gsub(/./, "=", longest); print "/=" longest "=\\"; n = length(longest); for(i = 1; i <= NR; ++i) { printf("| %s %*s\n", lines[i], n - length(lines[i]) + 1, "|"); } print "\\=" longest "=/" }' 

expand заменяет вкладки, которые могут быть на выходе с соответствующим количеством пробелов, чтобы сохранить внешний вид его такой же (чтобы каждый байт вывода отображался с одинаковой шириной). Код AWK работает следующим образом:

length($0) > length(longest) { # Remember the longest line 
    longest = $0 
} 
{        # also remember all lines in order 
    lines[NR] = $0 
} 
END {       # when you have everything: 
    gsub(/./, "=", longest)  # build a line of = as long as the longest 
           # line 
    print "/=" longest "=\\"  # use it to print the top bit 

    n = length(longest)   # format the content with left and right 
    for(i = 1; i <= NR; ++i) { # delimiters; spacing through printf 
    printf("| %s %*s\n", lines[i], n - length(lines[i]) + 1, "|") 
    } 

    print "\\=" longest "=/"  # print bottom bit. 
} 

наиболее безумный способ сделать это, и я осмелюсь вам оспаривать это, является с СЭД:

#!/bin/sed -f 

# assemble lines in the hold buffer, preceded by the left delimiter 
s/^/|/
1h 
1!H 
$!d 

# make a copy of it in the pattern space 
x 
h 

# isolate the longest line (or rather: a line of = as long as the longest 
# line) 
s/[^\n]/=/g 
:a 
/^\(=*\)\n\1/ { 
    s//\1/ 
    ba 
} 
//! { 
    s/\n=*// 
    ta 
} 

# build top bit, print it 
s,.*,/&\\, 
p 

# build measuring stick 
s,.\(.*\).,=\1, 

# for all lines in the output: 
:lineloop 

# fetch the line 
G 
s/^\(=*\n\)\([^\n]*\).*/\1\2/ 

# replace it with = to get a second measuring stick 
s/[^\n]/=/g 

# fetch another copy of the line 
G 
s/^\(=*\n=*\n\)\([^\n]*\).*/\1\2/ 

# inner loop: 
:spaceloop 

# while the line measuring stick is not as long as the overall measuring 
# stick 
/^\(=*\)\n\1/! { 
    # append a = to it and a space to the line for output 
    s/\n/\n=/ 
    s/$//
    b spaceloop 
} 

# once that is done, append the second delimiter 
s/$/|/ 
# remove one measuring stick 
s/=*\n// 
# put the second behind the actual line 
s/\(.*\)\n\(.*\)/\2\n\1/ 
# print the line 
P 
# remove it. Only the measuring stick remains and can be reused for the 
# next line 
s/.*\n// 

# do this while there are more lines to be processed 
x 
/\n/ { 
s/[^\n]*\n// 
x 
b lineloop 
} 

# then build the bottom bit and print it. 
x 
s/=/\\/ 
s/$/\// 

Положи в файле foo.sed, использование command | expand | sed -f foo.sed. Но сделайте это только один раз, чтобы подтвердить, что он работает. Вы не хотите запускать что-то подобное на производстве.

+0

Два способа, которые вы упомянули, велики , единственная проблема, с которой я столкнулся в данный момент, заключается в том, что, например, можно использовать фортификацию команды с любым из этих методов. Он вернет текстовое поле, которое выглядит так: [пример] (https://drive.google.com/file/d/0By-WW2LVuci6bHE1VHdteTYwbjg/view?usp=sharing). Это немного из-за расстояния или чего-то еще. Я не уверен, это случается только иногда, но мне нужно что-то, что будет работать идеально все время. Можете ли вы рассказать, что с ним не получается, на картинке, предоставленной –

+0

Некоторые состояния содержат символы табуляции, которые отображаются странно (они представляют собой один символ, но отображаются как многие). Чтобы исправить это, сначала проведите трубку: 'fortune | увеличить | awk allthatstuff' – Wintermute

+0

Спасибо, я бы не смог понять это без вашей помощи, и если бы у меня было, это было бы намного более грязно, чем то, что вы предоставили. Я действительно искренне это понимаю. Еще раз благодарю вас за все, что вы потратили на меня, что, кажется, слишком сложная проблема. –

0

Не на языке, что искал, но емкий и читают:

#!/usr/bin/env ruby 
input = STDIN.read.split("\n") 
width = input.map(&:size).max + 2 
bar = '='*(width-2) 
puts '/' + bar + '\\' 
input.each {|i| puts "|"+i+" "*(width-i.size-2)+"|" } 
puts '\\'+ bar + '/' 

Вы можете сохранить его в файл, chmod +x его, и труба ввода в нее.

Если вы «необходимость», чтобы он в однострочнике:

echo e"Apple\nPaper Clip\nWater" | 
ruby -e 'i=STDIN.read.split("\n");w=i.map(&:size).max+2;b="="*(w-2);i.map! {|j| "|"+j+" "*(w-j.size-2)+"|" };i.unshift "/"+b+"\\"; i<<"\\"+b+"/";puts i' 
Смежные вопросы