私が見つけたここBashから部分文字列を抽出する方法はありますが、パイピング後に適用する方法がわかりません。たとえば、
some func | echo ${string:12:5}
some func
変数に出力を割り当てる方法はstring
?
答え1
回答
出力を抽出する場合は、変数にsome_func
保存する必要はなく、cut
要求された文字を抽出するために出力を変数に送信するだけです。
some_func | cut -c 12-16
説明する
cut
stdin
要求された範囲は、指定されたオプションに従ってインポートおよび抽出されます。
-c
表現範囲は文字で指定されます。
12-16
文字範囲はで1
はなくindexで始まります0
。
したがって12
、13
および位置の文字が使用されます14
。15
16
〜のようにスティーブン・チャジェラス気になります。これは、最初の行だけでなくすべての入力行にも適用されます。
答え2
${string:offset:length}
変数の文字範囲に拡張するパラメータ拡張演算子です$string
。
シリーズを入手するにはバイト入力(単一バイト文字でも機能)では、次のものを使用できます。
func | tail -c +12 | head -c 5
12番目のバイトから始めて5バイトを取得します(1からオフセット)。オプションは標準-c
ではありませんが、head
一般的です。
func
head
この5バイトを出力した後に終了するので、16番目のバイトを出力した後に終了することができ、tail
後でより多くのデータを書き込もうとすると終了します。これはに影響を与えますfunc
。
次のようにすることもできます。
func | dd bs=1 skip=11 count=5 2> /dev/null
2> /dev/null
これは最後にステータスメッセージが表示されないようにするためです。ただし、これによりすべてのエラーが抑制されます。 GNUを使用すると、これを状態のみを抑制することに置き換えるdd
ことができます。status=none
値が大きいほど、length
一度に 1 バイトずつ読み取るため、効率が悪くなります。もう一度GNUを使用すると、dd
次のことを行うことでこの問題を回避できます。
func | dd iflag=count_bytes,skip_bytes,fullblock skip=11 bs=64k count=5M status=none
5MiBバイトのデータを取得するには、毎回最大64KiBを読み取ります。
バイトではなく文字(単一または複数バイト)で表されるオフセットと長さの場合、これはより複雑になります。
1つのオプションは、出力全体を変数に格納し、${var:offset:length}
演算子を使用することです。他の人が見せたように。ただし、これは出力全体をメモリに保存することを意味します。また、使用すると、末尾のvar=$(func)
改行文字が削除されることを意味します。
別のオプションは、bash
'sを使用してread -N
与えられた金額を読むことです。数値:
func | {
IFS= read -rN 11 discarded
IFS= read -rN 5 data
printf '%s\n' "$data"
}
または、以下を使用しますperl
(ビッグデータの場合は少し効率的です)。
func | perl -Mopen=locale -sne '
BEGIN{$total = $o + $n; $/ = \$total}
print substr($_, $o); exit' -- -o=10000 -n=5000000
答え3
string="$(func)"
echo "${string:12:5}"