bash:从标准输入读取直到字符串分隔符

bash:从标准输入读取直到字符串分隔符

假设我有两个包含任意字节的文件:./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(唯一可以在其变量中存储任意字节序列的 shell),假设datadelimiter是常规(或至少是 mmap()able)文件,您可以执行以下操作:

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

相关内容