パイプ出力でサブストリングをエコーする方法は?

パイプ出力でサブストリングをエコーする方法は?

私が見つけたここBashから部分文字列を抽出する方法はありますが、パイピング後に適用する方法がわかりません。たとえば、

some func | echo ${string:12:5}

some func変数に出力を割り当てる方法はstring

答え1

回答

出力を抽出する場合は、変数にsome_func保存する必要はなく、cut要求された文字を抽出するために出力を変数に送信するだけです。

some_func | cut -c 12-16  

説明する

cutstdin要求された範囲は、指定されたオプションに従ってインポートおよび抽出されます。

-c表現範囲は文字で指定されます。

12-16文字範囲はで1はなくindexで始まります0
したがって1213および位置の文字が使用されます141516

〜のようにスティーブン・チャジェラス気になります。これは、最初の行だけでなくすべての入力行にも適用されます。

答え2

${string:offset:length}変数の文字範囲に拡張するパラメータ拡張演算子です$string

シリーズを入手するにはバイト入力(単一バイト文字でも機能)では、次のものを使用できます。

func | tail -c +12 | head -c 5

12番目のバイトから始めて5バイトを取得します(1からオフセット)。オプションは標準-cではありませんが、head一般的です。

funcheadこの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}"

関連情報