Digamos que eu tenha dois arquivos contendo bytes arbitrários: ./delimiter
e ./data
.
Quero ler ./data
até e excluindo a primeira ocorrência da sequência de bytes em ./delimiter
.
Como eu faria isso usando o Bash?
Exemplo:
- Conteúdo de
./delimiter
world
- Conteúdo de
./data
helloworld
- Resultado esperado:
hello
Pergunta semelhante/equivalente:
Nota: read -d delim
não resolve meu problema, pois suporta apenas um delimitador de caractere único, não uma string. Além disso, armazena o resultado em uma variável e as variáveis não suportam NUL
bytes. Eu quero a saída em stdout
.
Responder1
Perl para o resgate!
perl -e 'local $/;
open $de, "<", "delimiter" or die $!;
$/ = <$de>;
open $da, "<", "data" or die $!;
chomp( $first = <$da> );
print $first;'
A variável especial$/define o separador de registro de entrada, porlocalAo fazer isso, leremos o arquivo inteiro (também chamado de "slurping"). Em seguida, usamos o operador diamante para ler o delimiter
arquivo e definir o separador para seu conteúdo. Em seguida, lemos o primeiro registro do data
arquivo,mastigarseparando o separador de registros dele.
Responder2
Com zsh
(o único shell que pode armazenar sequências de bytes arbitrárias em suas variáveis), assumindo data
e delimiter
são arquivos regulares (ou pelo menos mmap() capazes), você pode fazer:
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]*}
Ou:
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]
(não espere que seja muito eficiente nem que seja bem dimensionado para arquivos maiores que algumas centenas de megabytes).
Para imprimir essa parte literalmente, use:
print -rn -- $firstpart
Ou
printf %s $firstpart