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

相關內容