bash:標準入力から文字列区切り文字まで読みます。

bash:標準入力から文字列区切り文字まで読みます。

ランダムバイトを含む2つのファイルがあるとし./delimiterます./data

./dataバイトシーケンスが最初に表示されるまで読んで除外したいと思います./delimiter

Bashを使ってこれを行うにはどうすればよいですか?

例:

  • コンテンツ./delimiter
    world
    
  • コンテンツ./data
    helloworld
    
  • 予想される結果:
    hello
    

類似/同等の質問:

注:read -d delim文字列ではなく単一文字区切り文字のみをサポートしているため、問題は解決されません。また、バイトをサポートしていない変数に結果を格納しますNUL。私は出力が欲しいですstdout

答え1

Perlが救出に来る!

perl -e 'local $/;
         open $de, "<", "delimiter" or die $!;
         $/ = <$de>;
         open $da, "<", "data" or die $!;
         chomp( $first = <$da> );
         print $first;'

特殊変数$/次のように入力レコード区切り記号を設定します。地元のこれを使用してファイル全体を読み込みます(「slurping」とも呼ばれます)。次に、ダイヤモンド演算子を使用してファイルの内容を読み取り、delimiterその内容に区切り文字を設定します。次に、ファイルから最初のレコードを読み取りますdata噛むレコード区切り記号を抽出します。

答え2

zsh(変数にランダムなバイトシーケンスを格納できる唯一のシェル)を使用し、通常のdatadelimiterまたは少なくともmmap()可能)ファイルであると仮定すると、次のことができます。

zmodload zsh/mapfile

set +o multibyte # necessary so sequences of bytes that
                 # happen to form valid characters may be
                 # broken in the middle if necessary.

firstpart=${mapfile[data]%%$mapfile[delimiter]*}

または:

zmodload zsh/mapfile
set +o multibyte # necessary so sequences of bytes that
                 # happen to form valid characters may be
                 # broken in the middle if necessary.

delimiter=$mapfile[delimiter]
parts=( ${(ps[$delimiter])mapfile[data]} )

firstpart=$parts[1]

(非常に効率的または数百メガバイトより大きいファイルにうまく拡張されると期待しないでください)。

このセクションをそのまま印刷するには、次を使用します。

print -rn -- $firstpart

または

printf %s $firstpart

関連情報