部分文字列を文字列に列として追加する方法

部分文字列を文字列に列として追加する方法

タイトルは問題を説明するのに最も適していないかもしれませんが、私がやろうとしていることを続けて説明することは私が思い出すことができる最善です。私はOSとして、artix runitを使用して、次へのシンボリックリンクを作成します。サービスなので、簡単にするためにこのスクリプトを作成しました。

#!/bin/sh

rundir="/run/runit/service"
svdir="/etc/runit/sv"

for SERVICE in $(ls $svdir); do
    [[ -d "$rundir/$SERVICE" ]] && output="$output$SERVICE        linked: yes\n" || output="$output$SERVICE        linked: no\n"
done

service=$(printf "$output" | dmenu -l 10) || exit 1

if printf "$service" | grep -Fqe "linked: yes"; then
    service=$(printf "$service" | awk '{print $1}')
    sudo -A rm "$rundir/$service"
else
    service=$(printf "$service" | awk '{print $1}')
    sudo -A ln -s "$svdir/$service" "$rundir/"
fi

有効にできるすべてのサービスを確認し、存在するかどうかを/etc/runit/sv確認して、すでに有効になっていることを確認します。存在する場合はdmenuリストの末尾に/run/runit/service追加し、それ以外の場合はサービス名が異なるという問題を追加します。したがって、これを追加すると、次の不一致が発生します。 linked: yeslinked: no一貫性のない

ご覧のとおり、サービス名によって末尾にテキストの位置が変わるので、目にあまり魅力的ではなく、解決策がないかどうかを尋ねたいと思います。問題を解決できるので、最初に追加しますが、linked: xxxこれが最後の手段です。コードを書くより効率的な方法を指摘したい人がいる場合は、そうします。これは私の最初のbashスクリプトで、まだ学ぶことがたくさんあります。注:私はshでダッシュを使用しているので、いかなる種類のbashismも使用できません。

答え1

printfを使用して、パラメータの形式を特定の長さで指定できます。必要に応じて調整して20文字の左揃えを選択しました。

dメニュースクリーンショット

コードをいくつか調整してください。

#!/bin/sh

rundir="/run/runit/service"
svdir="/etc/runit/sv"

cd "$svdir"
result=$(
    for service in *; do
        printf '%-20s linked: %s\n' "$service" $([ -d "$rundir/$service" ] && echo yes || echo no)
    done | dmenu -l 10
) || exit 1

service=$(echo "$result" | awk '{print $1}')
case $result in
    *yes)
        sudo -A rm "$rundir/$service"
        ;;
    *no)
        sudo -A ln -s "$svdir/$service" "$rundir/"
esac

変更リスト:

  • [ expression ]テスト用に[[ ... ]]ダッシュに表示されない
  • *代わりに動作させるにはls1つが必要です。cd
  • 変数を削除$outputし、ループの出力を次にパイプします。dmenu
  • if-elseの代わりにCase文

関連情報