私は文字列を取得し、最大文字幅を設定し、限界に近い、または限界の行を単語で分割し、内容全体を整理する方法を研究してきました。
printf
配列とループを使用してこれを実行しましたが、for
迷惑です。たとえ初心者ですが、*毎回すべての作業を行う必要があります。
関数を作成し、文字列をパラメータとして渡したいと思います。私は実際にこれを行う方法の例を見つけましたが、私がコードを作成するのに十分な理解を持っていないので、コードを使用するのは怖いです。私が見つけたものは、次のパラメータでは機能しないので必須です。プロセスリダイレクトとコマンドの組み合わせですfmt
。私は無限に試しましたが、成功しませんでした。その後、fold
マニュアルページで見つかった参照を試しました。fmt
ここにあるドキュメントを使ってファイルにリダイレクトしてからfmt
整理できると思います。しかし、ファイルシステムを使用するprintf
ことはtrap
何らかの方法で避けたいと思います。
printMESSAGEBOX
これが私が得たものです。コードの関数です。
#!/usr/bin/env bash
# FORMATING: BOX DRAWING
boxp=" " ; boxP=" " ; boxt=" ╭────────────────────────────────────────────────────────────────────────╮" ; boxb=" ╰────────────────────────────────────────────────────────────────────────╯" ; boxT="╭─────────────────────────────────────────────────────────────────────────────╮" ; boxB="╰─────────────────────────────────────────────────────────────────────────────╯" ; boxl=" │ " ; boxL="│ " ; boxr=" │"
# FORMATING: FOREGROUND/TEXT
ñbla () { tput setaf 0;} ; ñred () { tput setaf 1;} ; ñgre () { tput setaf 2;} ; ñyel () { tput setaf 3;} ; ñblu () { tput setaf 4;} ; ñmag () { tput setaf 5;} ; ñcya () { tput setaf 6;} ; ñwhi () { tput setaf 7;}
# FORMATING: BACKGROUND/HIGHLIGHTING
ññbla () { tput setab 0;} ; ññred () { tput setab 1;} ; ññgre () { tput setab 2;} ; ññyel () { tput setab 3;} ; ññblu () { tput setab 4;} ; ññmag () { tput setab 5;} ; ññcya () { tput setab 6;} ; ññwhi () { tput setab 7;}
# FORMATING: MISC (HIGHLIGHT-STANDOUT-ON/HIGHLIGHT-STANDOUT-OFF/RM-STYLE-BOLD-OFF/BOLD-ON/UNDERLINE-ON/UNDERLINE-OFF)
ñH () { tput smso;} ; ñh () { tput rmso;} ; ñ0 () { tput sgr0;} ; alias ñb="ñ0" ; ñB () { tput bold;} ; ñU () { tput smul;} ; ñu () { tput rmul;}
# EXIT CLEANUP
trap ñ0 SIGINT
# MESSAGE PRINTING - REVISED CODE
printBOXHEADER() {
# SORT OUT INPUT
while [ "$1" != "" ]; do
case "$1" in
--type) shift; type=$1 ;;
--t0) type=0 ;; # don't print
--t1) type=1 ;; # green checkmark
--t2) type=2 ;; # red crossmark
--t3) type=3 ;; # custom icon
--t4) type=4 ;; # custom icon, custom color
--ic) shift; ic=$1 ;;
--ic-red) ic=red ;; # only obeyed with types 4
--ic-gre) ic=gre ;; # only obeyed with types 4
--ic-yel) ic=yel ;; # only obeyed with types 4
--ic-blu) ic=blu ;; # only obeyed with types 4
--ic-mag) ic=mag ;; # only obeyed with types 4
--ic-cya) ic=cya ;; # only obeyed with types 4
--ic-whi) ic=whi ;; # only obeyed with types 4
--icon) shift; icon=$1 ;; # single character/emoji, # only obeyed with types 3,4
--header) shift; header="$1" ;; # optional
esac
shift
done
# DO THAT THING YOU DO
if [[ $type -eq 0 ]]; then
return 0
elif [[ $type -eq 1 ]]; then
echo "[$(ñgre) ✔︎ $(ñ0)] $header"
elif [[ $type -eq 2 ]]; then
echo "[$(ñred) ✖︎ $(ñ0)] $header"
elif [[ $type -eq 3 ]]; then
echo "[ $icon ] $header"
elif [[ $type -eq 4 ]]; then
echo "[$(ñ$ic) $icon $(ñ0)] $header"
fi
}
# MESSAGE PRINTING - HAPHAZARD CODE
msgprint() {
printf "%s\n" "$boxt"
for line in "${msg[@]}"; do
printf "%s%s%s%s\n" "$boxl" "$line" "${boxp:${#line}}" "$boxr"
done
printf "%s\n" "$boxb"
}
msgprintw() {
printf "%s\n" "$boxT"
for line in "${msg[@]}"; do
printf "%s%s%s%s\n" "$boxL" "$line" "${boxP:${#line}}" "$boxr"
done
printf "%s\n" "$boxB"
}
printMESSAGEBOX() {
if [[ $widerbox =~ y ]]; then
msgprintw
elif [[ $widerbox =~ n ]]; then
msgprint
elif [[ $widerbox =~ x ]]; then
return
fi
}
widerbox=n
msg=(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
"eiusmod tempor incididunt ut labore et dolore magna aliqua."
"Pellentesque nec nam aliquam sem et."
)
printBOXHEADER "$@"
printMESSAGEBOX
出力:
zx9:Scripting v$ messageBOXREVISITING
╭────────────────────────────────────────────────────────────────────────╮
│ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do │
│ eiusmod tempor incididunt ut labore et dolore magna aliqua. │
│ Pellentesque nec nam aliquam sem et. │
╰────────────────────────────────────────────────────────────────────────╯
zx9:Scripting v$
printBOXHEADER
私はそれが最初は同じ汚れた構造を持つコードの関数と同じであることを望みますprintMESSAGEBOX
。先行スペースは意図的に存在し、使用されるときは整列されprintBOXHEADER
、使用されないときは注意を引くために存在します。少なくともそれが私たちの意図です。
私が試したことの1つは、fmt
これまで使用してきた配列に行を分割しようとしたことですprintf
。しかし、文字列全体を渡したり、各単語を分割したりするので、間違って引用したようです。もう一つの試み枠にはまっていて、自分のラインに合わせて枠にはまっていないのです。ほぼ全部受け取りました... :(
fmt
何でも歓迎し、高く評価します。私のアプローチから完全に外れた場合でも同様です(Bashとほとんどのシステムで一般的に使用されている以前のコマンド(例:... []の項目)を使用して実行される限り)。/usr
/bin
*: 言い換えれば、私はちょうどスクリプトを作成し始めました:)しかし、私のスキルが不足しても良いことがわかりません。
答え1
あなたは再発明をしているようです。箱、ほとんどのLinuxディストリビューション(debian、ubuntuなど)用にパッケージapt-get install boxes
化されています。
テキストを入力できますfmt
(またはより良い方法は基準)を入力してからを入力しますboxes
。
$ par -w 65 < /tmp/lorem | boxes -d stone
+----------------------------------------------------------------+
| Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed |
| do eiusmod tempor incididunt ut labore et dolore magna aliqua. |
| Pellentesque nec nam aliquam sem et. |
+----------------------------------------------------------------+
注:boxes
マルチバイト文字は現在構成ファイルではサポートされていません。githubの問題#72。使用できる美しいUnicode線描画文字が多いため、これは不幸なことです。この問題が最終的に解決されることを願っています。
boxes
ただし、入力テキストはマルチバイト入力文字をサポートします。およびANSIエスケープシーケンス(例:色)。ただし、サポートされておらず、fmt
正しくサポートされていませんpar
。どちらの手順も仮定します。1文字= 1バイト。
~によるとウィキペディア標準ページそして1.53ポールパッチです。Parにマルチバイト文字サポートを追加、マルチバイトパッチがありますが、par
まだアップストリームコードにマージされていないため、直接パッチを適用して再構築する必要があるかもしれません。
答え2
インスピレーションが来たときに別のスクリプトを更新する方法に切り替えましたが、mapfile
これは本当に簡単です。
ファイルを配列にリダイレクトします。
mapfile -t <arbitratyNameForArray> < filename.txt
しかし、同じことがまた起こりました。それはファイルを受け入れ、変数や何かを即座に注入したいと思います。
読書バッシュリファレンスマニュアル、とても役に立つシェルチェックウィキ、リンクが消えたランダムなウェブサイトなど、いよいよ得ました。
リダイレクトが何であるか、代替が何であるかをよりよく識別する必要があります。特にここでは次のようになります。
mapfile -t <arbitratyNameForArray> < <(some process)
ShellCheck Wikiに答えがあります。実際には2つあります。しかし、私はまだ私が理解して思い出したことを確認するために何かをしようとしました。
msg="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pellentesque nec nam aliquam sem et. Nisi vitae suscipit tellus mauris a diam maecenas sed enim. Sodales ut etiam sit amet nisl purus. Fermentum posuere urna nec tincidunt praesent. Velit dignissim sodales ut eu sem integer vitae justo. Justo donec enim diam vulputate ut pharetra sit amet."
arrayDone=()
while IFS='' read -r line; do
arrayDone+=("$line")
done < <(fmt -w 76 <(echo "$msg"))
for arrayLine in "${arrayDone[@]}"; do
printf "%s%s%s\n" "⚡️" "$arrayLine" "↩️"
done
出力:
zx9:Scripting v$ fmtter
⚡️Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod↩️
⚡️tempor incididunt ut labore et dolore magna aliqua. Pellentesque nec nam↩️
⚡️aliquam sem et. Nisi vitae suscipit tellus mauris a diam maecenas sed enim.↩️
⚡️Sodales ut etiam sit amet nisl purus. Fermentum posuere urna nec tincidunt↩️
⚡️praesent. Velit dignissim sodales ut eu sem integer vitae justo. Justo donec↩️
⚡️enim diam vulputate ut pharetra sit amet.↩️
zx9:Scripting v$
これで実際のコードに適用する必要があります。
どのように動作しますか?
まず、arrayDone=()
配列を使用する前に単に配列を宣言します。while IFS='' read -r line; do arrayDone+=("$line") done
;while
ループ obvi を起動し、IFS=''
単語区切り文字で空白文字を削除します。無限に読み取る必要があるのは、サブシェルでのみ実行するか、一部の分離を使用する必要があります。それ以外の場合、混乱が発生します...どのような考えがありますか?私が言ったことはすべて忘れてしまい、私が説明がうまくいかなかったので、ここにある文書と比較してみようと落書きをして+ファイルにリダイレクトをしたところ、理解しやすくなります。ここで私を助けてくれた多くの人のように、少なくとも一人でも助けることができたらと思います。 :)
ありがとうございます!