私はいくつかのシェルがこの種のテストを可能にすることを知っています。
t() { [[ $var == *$'\n'* ]] && res=yes || res=no
printf '%s ' "$res";
}
var='ab
cd'
t
var='abcd'
t
echo
実行時:
$ bash ./script
yes no
POSIXに対応するタスクは何ですか(ダッシュ)
次のテスト方法は信頼できますか?
nl=' ' t() { case "$var" in *$nl* ) res=yes ;; * ) res=no ;; esac printf '%s ' "$res" } var='ab cd' t var='abcd' t echo
答え1
変数に新しい行を入れてパターンマッチングを実行できますcase
。
$ cat nl.sh
#!/bin/sh
nl='
'
case "$1" in
*$nl*) echo has newline ;;
*) echo no newline ;;
esac
$ dash nl.sh $'foo\nbar'
has newline
$ dash nl.sh $'foobar'
no newline
改行を作成する別の方法は次のとおりです。
nl=$(printf "\nx"); nl=${nl%x}
明らかなコマンド置換は、置換が末尾の改行を削除するため、機能しません。
答え2
はい、
nl='
'
case $var in
(*"$nl"*) echo yes;;
(*) echo no;;
esac
case
(原則として、パターンとして扱われたくない限り、パターン内ですべての変数拡張を引用したいのですが、ここでは$nl
ワイルドカードが含まれていないため違いはありません。)
または
case $var in
(*'
'*) echo yes;;
(*) echo no;;
esac
すべてがうまく機能し、POSIXと互換性がなければならず、これが私が使用するでしょう。 sを削除すると、(
以前のBourneシェルでも機能します。
変数を設定する$nl
別の方法:
eval "$(printf 'nl="\n"')"
気づく$'\n'
POSIX規格の次のバージョンに含まれる予定。少なくともksh93
、、、、 busybox 、およびFreeBSDでサポートされています(2018年2月現在)zsh
。bash
mksh
sh
保持しているテストが十分かどうかについて両方のケースでテストしたので、すべてのコードパスがテストされます。
現在のPOSIX仕様に明示的に指定されていないことは、*
有効な文字を形成しないバイト列が含まれる文字列を一致させるかどうか、またはシェル変数にこれらの文字列を含めることができるかどうかです。
実際には、変数に文字しか含めることができないことを除いて、NULバイト以外の文字列を含む文字列yash
(シェルはできませんがzsh
変数に格納できます)は、有効なバイト列を形成しない文字が含まれていても一致する必要があります。 (UTF-8など)。*$nl*
$nl
$'\x80'
たとえば、一部のfind
実装は-name "*$nl*"
一致しないため、新しいシェルをテストし、テキスト(ファイル名など)が保証されていない項目を処理したい場合は、これにテストケースを追加できます。 。次のように:
test=$(printf '\200\n\200')
UTF-8ロケール。