cutコマンドが与えられた文字列を分割しないのはなぜですか?

cutコマンドが与えられた文字列を分割しないのはなぜですか?

ここで、カットは期待どおりに機能します。

$ cat test 
1;2;3;4
$ cut -d ';' -f 2 test 
2
$ cut -d ';' -f 3 test 
3

しかし、ここでは「21」を出力したいと思います。私が何を間違っているのでしょうか?

$ updates=""
$ echo "$updates" | cat -v

$ updates=$(/usr/lib/update-notifier/apt-check 2>&1);echo $updates
21;0
$ echo "$updates" | cat -v
21;0
$ updates=""
$ updates=$(/usr/lib/update-notifier/apt-check 2>&1);echo $updates | 
cut -d ";" -f 1
21
$ echo "$updates" | cat -v
21;0

Stéphanesソリューションを試してみると

$ cat test2.sh 
updates=$(/usr/lib/update-notifier/apt-check)
all=${updates%";"*}
security=${updates#*";"}
printf '%s\n' "$all packages can be updated" \
          "$security updates are security updates"
$ ./test2.sh 
21;0 packages can be updated
updates are security updates

ベストアンサー1

コマンドの標準出力と標準エラー(末尾の改行を除く)を変数に割り当てるには、POSIXに似たシェルの構文は次のとおりです。

updates=$(/usr/lib/update-notifier/apt-check 2>&1)

改行文字が追加された変数の内容を出力するには、構文は次のとおりです。

printf '%s\n' "$updates"

変数の内容を文字に分割する構文は次のとおりです。

IFS=';'
set -o noglob
set -- $updates

printf '%s\n' "First element: $1" "Second element: $2"

またはこれを行うこともできます:

updates=$(/usr/lib/update-notifier/apt-check 2>&1)
all=${updates%";"*}
security=${updates#*";"}
printf '%s\n' "$all packages can be updated" \
              "$security updates are security updates"

等しいものを得るために

/usr/lib/update-notifier/apt-check --human-readable

cut以下を使用して、変数各行の最初のセミコロンで区切られたフィールドを取得することもできます。

printf '%s\n' "$updates" | cut -d ';' -f 1

しかし、変数に行が1つしかない場合は過剰です。

おすすめ記事