kshスクリプトの3つの変数のうちの1つから3つの単語を抽出したいと思います。 ksh93でこの行を使用しましたが、うまく動作します。
read A B C <<< $line
ksh88で上記のコマンドを実行すると、次のエラーが発生します。
syntax error at line ## : '<' unexpected
ksh88で同じことをどのように実行できますか?
答え1
ksh88
いいえ、ここの文字列はおよびで使用できませんpdksh
。ただし、最新ksh93
(オリジナルのAT&T Korn Shell)および(mksh
現在活発に開発されているpdksh
スピンオフ)で利用可能です。
<<<
はいksh93
、、mksh
GNU bash
、およびzsh
。
あなたの具体的な質問...
read A B C <<< $line
...この問題を解決できます(Kornシェル)。
print -r -- $line |&
read -p A B C
これを使用することもできますが(POSIXシェル)、tmpfileのパフォーマンスが低下します(一方である可能性<<<
があります)。
read A B C <<EOF
$line
EOF
しかし、単語を分離したい場合は、次のようにします。
set -A arrname -- $line
${arrname[0]}
その後、代わりに使用し$A
て${arrname[1]}
交換してください$B
。 3つの要素に分割されても止まらないということだけです。したがって、$line
「foo bar baz bla
」の場合は$C
「baz bla」が含まれ、${arrname[2]}
「baz」がある場合は${arrname[3]}
「bla」が含まれます。
ただし、位置パラメーターが不要な場合は、次のことができます。
set -- $line
A=$1; shift
B=$1; shift
C=$*
ただし、単語数が3個未満の場合はエラーが発生します(不明な場合は確認するかshift
(潜在的に遅い)確認を最初に使用してください)。$line
$#
[[ $line = *' '*' '[! ] ]]
これはset … $line
ワイルドカードも行います(上記のStéphaneに感謝します)、以前に必要ですset -o noglob
(通常は後で以前の状態を復元できますset +o noglob
)。
完全な公開:私はmksh
開発者です。
答え2
いいえ、ここの文字列はzsh
1991年2.0(および/またはUnixポート)から取得されましたrc
。それぞれの作者は当時のアイデアを交換し、2人のうち誰がアイデアを持っているのか、彼のシェルの最初の真ん中に含めたのかはわかりません。
2.05b(2002)のbash、m+(2002)のksh93、R33(2008)のmksh、2.7(2009)のyashに追加されました。
ksh88には新機能はありません。
ここにある文書(<<
)自体は、1970年代後半のBourne-shellからのものです。
read A B C
一つ読んでください論理的行は非常に特定の方法で挿入され、A
変数B
(デフォルトはIFS空白文字1のみを含むややあまり具体的ではありませんC
)$IFS
とバックスラッシュがエスケープおよび行連続文字として機能するため、これC
も非常に複雑になります。なしで同じことをするのは非常に難しいでしょうread
。
とにかくここ<<<
と同じで<<
構文だけが異なります。
read A B C << EOF
$var
EOF
まったく同じ
read A B C <<< "$var" # note that some versions of bash need the quotes
すべての殻に。どちらの場合も、シェルは内容と追加された改行文字を含む削除された一時ファイルを生成します(一部のシェルは代わりにパイプを使用します)。それではread
読んでください。論理的行(バックスラッシュで続く複数の物理行に存在する可能性があります)を入力し、複雑なルールを使用して変数を入力します。
$var
to(SPC/TAB区切り)の最初の3ワードのみを割り当て $A
、$B
$C
$IFS
まだデフォルト値が含まれています。- 変数にバックスラッシュと改行文字が含まれていません。
- この変数には3つの単語のみが含まれています。
最初の3つの単語に対して、次のことができます。
function split_into {
typeset words IFS v i=0
set -o noglob
set -A words -- $1; shift
for v do
eval "$v=\${words[i]}"
((i += 1))
done
}
split_into "$var" A B C
^IFS スペース文字、各POSIXはロケールに分類された文字であり、ksh88(POSIX仕様のベース)とほとんどのシェルで発生する[:space:]
ように、これはまだSPC、TAB、およびNLに制限されています。$IFS
これに関して私が見つけた唯一のPOSIX互換シェルはですyash
。ksh93
(bash
5.0ベース)他のスペース(CR、FF、VTなど)も含まれていますが、シングルバイトスペースに制限されています(たとえば、Solaris)(一部の領域にはシングルバイトの切り捨て防止スペースが含まれています)