মুদ্রণগুলিতে মুদ্রিত অক্ষর


107

আমি কোনও প্রক্রিয়া চলছে কিনা তা প্রদর্শনের জন্য বাশ শেল স্ক্রিপ্ট লিখছি।

এখনও পর্যন্ত, আমি এটি পেয়েছি:

printf "%-50s %s\n" $PROC_NAME [UP]

কোডটি আমাকে এই আউটপুট দেয়:

JBoss                                              [DOWN]

GlassFish                                          [UP]

verylongprocessname                                [UP]

আমি আরও ক্ষেত্রের মধ্যে ফাঁকটিকে '-' বা '*' দিয়ে আরও পাঠযোগ্য করে তুলতে চাই। ক্ষেত্রের সারিবদ্ধতা ব্যাহত না করে কীভাবে করব?

আমি যে আউটপুটটি চাই তা হ'ল:

JBoss -------------------------------------------  [DOWN]

GlassFish ---------------------------------------  [UP]

verylongprocessname -----------------------------  [UP]

উত্তর:


77

খাঁটি বাশ, কোনও বাহ্যিক সুবিধা নেই

এই প্রদর্শনটি সম্পূর্ণ ন্যায়সঙ্গততা করে, তবে আপনি যদি রাগড-ডান লাইনগুলি চান তবে আপনি কেবল দ্বিতীয় স্ট্রিংয়ের দৈর্ঘ্য বাদ দিয়ে বাদ দিতে পারেন।

pad=$(printf '%0.1s' "-"{1..60})
padlength=40
string2='bbbbbbb'
for string1 in a aa aaaa aaaaaaaa
do
     printf '%s' "$string1"
     printf '%*.*s' 0 $((padlength - ${#string1} - ${#string2} )) "$pad"
     printf '%s\n' "$string2"
     string2=${string2:1}
done

দুর্ভাগ্যক্রমে, সেই কৌশলটিতে প্যাড স্ট্রিংয়ের দৈর্ঘ্য আপনার প্রয়োজন মনে করা দীর্ঘতমের চেয়ে দীর্ঘতর হতে হবে, তবে প্যাডলাইথটি প্রদর্শিত হিসাবে পরিবর্তনশীল হতে পারে। তবে, প্যাডের দৈর্ঘ্যের জন্য একটি ভেরিয়েবল ব্যবহার করতে সক্ষম হতে আপনি এই তিনটি দিয়ে প্রথম লাইনটি প্রতিস্থাপন করতে পারেন:

padlimit=60
pad=$(printf '%*s' "$padlimit")
pad=${pad// /-}

সুতরাং প্যাড ( padlimitএবং padlength) টার্মিনাল প্রস্থের উপর ভিত্তি করে ( $COLUMNS) বা দীর্ঘতম স্ট্রিংয়ের দৈর্ঘ্য থেকে গণনা করা যেতে পারে ।

আউটপুট:

a--------------------------------bbbbbbb
aa--------------------------------bbbbbb
aaaa-------------------------------bbbbb
aaaaaaaa----------------------------bbbb

দ্বিতীয় স্ট্রিংয়ের দৈর্ঘ্য বিয়োগ ছাড়াই:

a---------------------------------------bbbbbbb
aa--------------------------------------bbbbbb
aaaa------------------------------------bbbbb
aaaaaaaa--------------------------------bbbb

পরিবর্তে প্রথম লাইনটি সমতুল্য হতে পারে (অনুরূপ sprintf):

printf -v pad '%0.1s' "-"{1..60}

বা একইভাবে আরও গতিশীল কৌশলটির জন্য:

printf -v pad '%*s' "$padlimit"

আপনি যদি পছন্দ করেন তবে আপনি সমস্ত এক লাইনে মুদ্রণটি করতে পারেন:

printf '%s%*.*s%s\n' "$string1" 0 $((padlength - ${#string1} - ${#string2} )) "$pad" "$string2"

1
আপনি কি কিছুটা প্রিন্টফ '% *। * এস' ... অংশ ব্যাখ্যা করতে পারবেন?
ouডার্ড লোপেজ

3
@ এডওয়ার্ড লোপেজ: প্রথম অ্যাসিড্রিকটি আর্গুমেন্ট তালিকার শূন্য দ্বারা প্রতিস্থাপিত হয়েছে। দ্বিতীয় তাত্ক্ষণিকটি দ্বিতীয় যুক্তিতে গণনার ফলাফল দ্বারা প্রতিস্থাপিত হয়। ফলাফল, উদাহরণস্বরূপ, "আআআআ" এবং "বিবিবিবিবি" স্ট্রিংগুলির জন্য '%0.31s'। স্ট্রিং (চূড়ান্ত যুক্তি) বিন্দুর পরে নির্দিষ্ট দৈর্ঘ্যে কাটা হয়। শূন্য কোনও স্থান প্যাডিং আউটপুট হতে বাধা দেয়। সুতরাং 31 হাইফেন আউটপুট হয়।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

1
এই পৃষ্ঠাটি ডেনিস উইলিয়ামসনের উত্তরটি বুঝতে সহায়তা করতে পারে: উইকি.বাশ- হ্যাকারস.আর
লোপেজ

{1..60} 60 এর পরিবর্তনশীল হিসাবে প্রয়োজন; ... যেমন "var = 60"
রেগান মিরান্ডা

@ রিগানমিরান্ডা: এই কৌশলটি যেভাবে কাজ করে তা হ'ল আপনার প্রয়োজন সবচেয়ে বড়টির মানটিকে হার্ড কোড করুন এবং padlengthআউটপুটে প্রকৃত দৈর্ঘ্য নির্বাচন করতে ব্যবহার করুন।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

68

খাঁটি বাশ স্থির স্ট্রিং 'লাইন' এর অফসেট হিসাবে 'PROC_NAME' এর মান দৈর্ঘ্যটি ব্যবহার করুন:

line='----------------------------------------'
PROC_NAME='abc'
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}"
PROC_NAME='abcdef'
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}"

এই দেয়

abc ------------------------------------- [UP]
abcdef ---------------------------------- [UP]

যাদুটি হ'ল {{লাইন: $ {# PROC_NAME}}, যা কেবলমাত্র ভেরিয়েবল লাইনের একটি বিন্দু থেকে প্রত্যাবর্তন শুরু করতে ব্যাশ সাবস্ট্রিং নিষ্কাশন ব্যবহার করে, যা PROC_NAME- এ অক্ষরের সংখ্যা থেকে শুরু করতে সেট করা আছে। tldp.org/LDP/abs/html/string-manipulation.html#SUBSTREXTR01
সিভরভ

মনে রাখবেন যে PROC_NAMEএটি ইতিমধ্যে পলায়ন না করে এমন জায়গাগুলির ক্ষেত্রে হ্যান্ডেল করে না । আপনি প্রতিটি দুটি টোকেন সহ একটি লাইন পাবেন এবং তারপরে আপনার পরিবর্তনশীলটিতে দুটি পৃথক পৃথক টোকেনের জন্য [UP] এবং তারপরে আপনার lineপাঠ্য বিয়োগের সাথে আপনার ইনপুট স্ট্রিংয়ের মোট দৈর্ঘ্য সহ একক লাইন পাবেন । সুতরাং সাবধান হন, যেহেতু এটি কোনও জটিল স্ক্রিপ্টে করা গেলে আকর্ষণীয় এবং সম্ভাব্য নিরাপত্তাহীন বাগগুলি হতে পারে। অন্যথায় সংক্ষিপ্ত এবং সহজ। :)
ডোডেক্সাহেড্রন

19

তুচ্ছ (তবে কার্যকারী) সমাধান:

echo -e "---------------------------- [UP]\r$PROC_NAME "

4
তবে শুধুমাত্র টার্মিনালে। আউটপুট যদি কোনও ফাইলে প্রেরণ করা হয় তবে তা গোলযোগ হবে।
থকাল

5
সুতরাং আপনি কি সত্যিই একটি তুচ্ছ সমাধান থেকে প্রত্যাশা ?!? আউটপুট পুনর্নির্দেশের সাথে পুরো কাজ করছে?!? ]: পি
নিকোলা লিওনি

14

আমি মনে করি এটিই সহজ সমাধান। খাঁটি শেল বিল্টিনস, কোনও ইনলাইন গণিত নেই। এটি পূর্ববর্তী উত্তরগুলি থেকে ধার করে।

কেবলমাত্র সাবস্ট্রিংস এবং $ {# ...} মেটা-ভেরিয়েবল।

A="[>---------------------<]";

# Strip excess padding from the right
#

B="A very long header"; echo "${A:0:-${#B}} $B"
B="shrt hdr"          ; echo "${A:0:-${#B}} $B"

উত্পাদন

[>----- A very long header
[>--------------- shrt hdr


# Strip excess padding from the left
#

B="A very long header"; echo "${A:${#B}} $B"
B="shrt hdr"          ; echo "${A:${#B}} $B"

উত্পাদন

-----<] A very long header
---------------<] shrt hdr

12

স্পেস ব্যবহার করে কিছু দিয়ে প্যাড করার কোনও উপায় নেই printf। আপনি ব্যবহার করতে পারেন sed:

printf "%-50s@%s\n" $PROC_NAME [UP] | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /'

7
+1 একটি সমস্যা আছে যদি PROC_NAME এ কোনও ড্যাশ থাকে - সহজেই একটি অতিরিক্ত @:printf "%-50s@%s\n" ${PROC_NAME}@ [UP] | sed -e 's/ /-/g' -e 's/-@/ /' -e 's/@-/ /'
থিকালা

9
echo -n "$PROC_NAME $(printf '\055%.0s' {1..40})" | head -c 40 ; echo -n " [UP]"

ব্যাখ্যা:

  • printf '\055%.0s' {1..40}- 40 টি ড্যাশ তৈরি করুন
    (ড্যাশ বিকল্প হিসাবে ব্যাখ্যা করা হয় তাই পরিবর্তে এসকিআই কোড ব্যবহার করুন)
  • "$PROC_NAME ..." - কনেকেটনেট $ PROC_NAME এবং ড্যাশ
  • | head -c 40 - প্রথম 40 টি অক্ষরে স্ট্রিম ছাঁটাই

আশ্চর্যের বিষয়, যখন আমি printf 'x' {1..40}এটি করি কেবলমাত্র একক xহ্ম্ম্ম প্রিন্ট করি
ক্রিশ্চিয়ান

@ ক্রিশ্চিয়ান এর কারণ আপনি এই ফর্ম্যাটটি অনুলিপি করেন নি: `printf 'x% .0s' {1..40} 40 40 xs
artm

printf -- "-%.0s" {1..40}
ড্যাশটিকে

7

এটি একটি আরও সহজ এবং কোনও বাহ্যিক আদেশ ব্যবহার করে না।

$ PROC_NAME="JBoss"
$ PROC_STATUS="UP"
$ printf "%-.20s [%s]\n" "${PROC_NAME}................................" "$PROC_STATUS"

JBoss............... [UP]

5

সহজ তবে এটি কাজ করে:

printf "%-50s%s\n" "$PROC_NAME~" "~[$STATUS]" | tr ' ~' '- '

ব্যবহারের উদাহরণ:

while read PROC_NAME STATUS; do  
    printf "%-50s%s\n" "$PROC_NAME~" "~[$STATUS]" | tr ' ~' '- '
done << EOT 
JBoss DOWN
GlassFish UP
VeryLongProcessName UP
EOT

Stdout যাও আউটপুট:

JBoss -------------------------------------------- [DOWN]
GlassFish ---------------------------------------- [UP]
VeryLongProcessName ------------------------------ [UP]

4

echoশুধুমাত্র ব্যবহার

@ ডেনিস উইলিয়ামসনের অ্যাঞ্জার ঠিক ইকো ব্যবহার করে এটি করার চেষ্টা না করে ঠিক কাজ করছে fine ইকো একটি নির্দিষ্ট রঙের সাথে চারক্যাকটারগুলিকে আউটপুট দেয়। প্রিন্টফ ব্যবহার করে সেই রঙ মুছে ফেলা হবে এবং অপঠনযোগ্য অক্ষর মুদ্রণ করা হবে। এখানে একমাত্র echoবিকল্প:

string1=abc
string2=123456
echo -en "$string1 "
for ((i=0; i< (25 - ${#string1}); i++)){ echo -n "-"; }
echo -e " $string2"

আউটপুট:

abc ---------------------- 123456

অবশ্যই আপনি ডেনিস উইলিয়ামসনের প্রস্তাবিত সমস্ত প্রকরণগুলি ব্যবহার করতে পারেন আপনি ডান অংশটি বামে রাখতে চান - বা ডান-প্রান্তিককরণ ( ইত্যাদি 25 - ${#string1}দ্বারা প্রতিস্থাপন 25 - ${#string1} - ${#string2}...


2

এখানে অন্য একটি:

$ { echo JBoss DOWN; echo GlassFish UP; } | while read PROC STATUS; do echo -n "$PROC "; printf "%$((48-${#PROC}))s " | tr ' ' -; echo " [$STATUS]"; done
JBoss -------------------------------------------- [DOWN]
GlassFish ---------------------------------------- [UP]

2

আপনি যদি কোনও নির্দিষ্ট কলাম সংখ্যায় প্যাডের অক্ষরগুলি শেষ করে থাকেন, তবে আপনি ওপ্যাড এবং cutদৈর্ঘ্য করতে পারেন :

# Previously defined:
# PROC_NAME
# PROC_STATUS

PAD="--------------------------------------------------"
LINE=$(printf "%s %s" "$PROC_NAME" "$PAD" | cut -c 1-${#PAD})
printf "%s %s\n" "$LINE" "$PROC_STATUS"

2

স্বয়ংক্রিয় স্কেলিং / পুনরায় আকার দেওয়ার পদ্ধতি এবং উদাহরণ সহ সাধারণ কনসোল স্প্যান / ফিল / প্যাড / প্যাডিং।

function create-console-spanner() {
    # 1: left-side-text, 2: right-side-text
    local spanner="";
    eval printf -v spanner \'"%0.1s"\' "-"{1..$[$(tput cols)- 2 - ${#1} - ${#2}]}
    printf "%s %s %s" "$1" "$spanner" "$2";
}

উদাহরণ: create-console-spanner "loading graphics module" "[success]"

এখন এখানে একটি পূর্ণ-বৈশিষ্ট্যযুক্ত-বর্ণ-চরিত্র-টার্মিনাল-স্যুট যা স্প্যানারের সাহায্যে রঙ এবং শৈলীর বিন্যাসিত স্ট্রিং মুদ্রণের ক্ষেত্রে সমস্ত কিছু করে।

# Author: Triston J. Taylor <pc.wiz.tt@gmail.com>
# Date: Friday, October 19th, 2018
# License: OPEN-SOURCE/ANY (NO-PRODUCT-LIABILITY OR WARRANTIES)
# Title: paint.sh
# Description: color character terminal driver/controller/suite

declare -A PAINT=([none]=`tput sgr0` [bold]=`tput bold` [black]=`tput setaf 0` [red]=`tput setaf 1` [green]=`tput setaf 2` [yellow]=`tput setaf 3` [blue]=`tput setaf 4` [magenta]=`tput setaf 5` [cyan]=`tput setaf 6` [white]=`tput setaf 7`);

declare -i PAINT_ACTIVE=1;

function paint-replace() {
    local contents=$(cat)
    echo "${contents//$1/$2}"
}

source <(cat <<EOF
function paint-activate() {
    echo "\$@" | $(for k in ${!PAINT[@]}; do echo -n paint-replace \"\&$k\;\" \"\${PAINT[$k]}\" \|; done) cat;
}
EOF
)

source <(cat <<EOF
function paint-deactivate(){
    echo "\$@" | $(for k in ${!PAINT[@]}; do echo -n paint-replace \"\&$k\;\" \"\" \|; done) cat;    
}
EOF
)

function paint-get-spanner() {
    (( $# == 0 )) && set -- - 0;
    declare -i l=$(( `tput cols` - ${2}))
    eval printf \'"%0.1s"\' "${1:0:1}"{1..$l}
}

function paint-span() {
    local left_format=$1 right_format=$3
    local left_length=$(paint-format -l "$left_format") right_length=$(paint-format -l "$right_format")
    paint-format "$left_format";
    paint-get-spanner "$2" $(( left_length + right_length));
    paint-format "$right_format";
}

function paint-format() {
    local VAR="" OPTIONS='';
    local -i MODE=0 PRINT_FILE=0 PRINT_VAR=1 PRINT_SIZE=2;
    while [[ "${1:0:2}" =~ ^-[vl]$ ]]; do
        if [[ "$1" == "-v" ]]; then OPTIONS=" -v $2"; MODE=$PRINT_VAR; shift 2; continue; fi;
        if [[ "$1" == "-l" ]]; then OPTIONS=" -v VAR"; MODE=$PRINT_SIZE; shift 1; continue; fi;
    done;
    OPTIONS+=" --"
    local format="$1"; shift;
    if (( MODE != PRINT_SIZE && PAINT_ACTIVE )); then
        format=$(paint-activate "$format&none;")
    else
        format=$(paint-deactivate "$format")
    fi
    printf $OPTIONS "${format}" "$@";
    (( MODE == PRINT_SIZE )) && printf "%i\n" "${#VAR}" || true;
}

function paint-show-pallette() {
    local -i PAINT_ACTIVE=1
    paint-format "Normal: &red;red &green;green &blue;blue &magenta;magenta &yellow;yellow &cyan;cyan &white;white &black;black\n";
    paint-format "  Bold: &bold;&red;red &green;green &blue;blue &magenta;magenta &yellow;yellow &cyan;cyan &white;white &black;black\n";
}

কোনও রঙ মুদ্রণের জন্য , এটি যথেষ্ট সহজ: paint-format "&red;This is %s\n" red এবং আপনি পরে সাহসী হতে চাইতে পারেন:paint-format "&bold;%s!\n" WOW

-lবিকল্প paint-formatযাতে আপনি কনসোল ফন্ট বৈশিষ্ট্যের মান অপারেশন করতে পারি না ফাংশন টেক্সট পরিমাপ।

-vবিকল্প paint-formatফাংশন হিসাবে একই ভাবে কাজ করে printfকিন্তু সরবরাহকৃত করা যাবে না-l

এখন বিস্তৃত জন্য !

paint-span "hello " . " &blue;world" [দ্রষ্টব্য: আমরা নিউলাইন টার্মিনাল ক্রম যুক্ত করি নি, তবে পাঠ্যটি টার্মিনালটি পূরণ করে, সুতরাং পরবর্তী লাইনটি কেবল একটি নতুন লাইন টার্মিনাল ক্রম হিসাবে উপস্থিত হবে]

এবং এর ফলাফল:

hello ............................. world


0

প্যারামিটার সম্প্রসারণের অনুমতি দেওয়ার জন্য বাশ + সিক

@ ডেনিস উইলিয়ামসনের উত্তরের মতো, তবে যদি seqএটি পাওয়া যায় তবে প্যাড স্ট্রিংয়ের দৈর্ঘ্য হার্ডকোড করা উচিত নয়। নিম্নলিখিত কোডটি অবস্থানগত পরামিতি হিসাবে স্ক্রিপ্টে একটি ভেরিয়েবল পাস করার অনুমতি দেয়:

COLUMNS="${COLUMNS:=80}"
padlength="${1:-$COLUMNS}"
pad=$(printf '\x2D%.0s' $(seq "$padlength") )

string2='bbbbbbb'
for string1 in a aa aaaa aaaaaaaa
do
     printf '%s' "$string1"
     printf '%*.*s' 0 $(("$padlength" - "${#string1}" - "${#string2}" )) "$pad"
     printf '%s\n' "$string2"
     string2=${string2:1}
done

শেলটি কমান্ড ফ্ল্যাগ হিসাবে ব্যাখ্যা করে এড়াতে "-" অক্ষরের পরিবর্তে ASCII কোড "2D" ব্যবহৃত হয়। "=" ব্যবহারের জন্য অন্য বিকল্পটি "3D"।

আর্গুমেন্ট হিসাবে কোনও প্যাডেলেন্থের অভাবে পাস করার পরে, উপরের কোডটি 80 টি অক্ষরের মানক টার্মিনাল প্রস্থের ডিফল্ট হয়।

বাশ শেল ভেরিয়েবলের COLUMNS(যেমন, বর্তমান টার্মিনালের প্রস্থ) সুবিধা গ্রহণ করতে, পরিবেশের পরিবর্তনশীলটি স্ক্রিপ্টের জন্য উপলব্ধ হওয়া প্রয়োজন। একটি উপায় হ'ল .("ডট" কমান্ড) এর আগে স্ক্রিপ্টটি চালিয়ে সমস্ত পরিবেশের ভেরিয়েবল উত্স করা :

. /path/to/script

বা (আরও ভাল) COLUMNSনির্বাহ করার সময় স্পষ্টভাবে ভেরিয়েবলটি পাস করুন :

/path/to/script $COLUMNS
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.