任意のバイトを含む 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;'
特殊変数$/入力レコードセパレータを設定します。地元これを使用すれば、ファイル全体を読み込むことができます(「スラーピング」とも呼ばれます)。次に、ダイヤモンド演算子を使用してファイルから読み込みdelimiter
、セパレータをその内容に設定します。次に、ファイルから最初のレコードを読み込みdata
、かむそこからレコード区切り文字を削除します。
答え2
zsh
(任意のバイトシーケンスを変数に格納できる唯一のシェル)では、data
と がdelimiter
通常のファイル (または少なくとも 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