Comando integrado Bash mapfile


0

Comando integrado Bash mapfile

comando mapfile

Em sistemas operacionais do tipo Unix, mapfile é um comando embutido do shell Bash. Ele lê as linhas da entrada padrão em uma variável de matriz indexada.

Gorjeta

Para obter mais informações sobre as variáveis ​​de array do bash, consulte arrays no bash.

Sintaxe

mapfile [-n count] [-O origin] [-s count] [-t] [-u fd]
        [-C callback [-c quantum]] [array]

Opções

O comando mapfile embutido usa as seguintes opções:

-n contagem

Leia um máximo de linhas de contagem. Se a contagem for zero, todas as linhas disponíveis serão copiadas.

-O origem

Comece a escrever linhas na matriz da matriz na origem do número de índice. O valor padrão é zero.

-s contagem

Descarte as primeiras linhas de contagem antes de gravar na matriz.
-t Se alguma linha terminar em uma nova linha, retire-a.

-u fd

Leia as linhas do descritor de arquivo fd em vez da entrada padrão.

-C callback

Executa \/avalia uma função \/expressão, retorno de chamada, toda vez que as linhas quânticas são lidas. O valor padrão de quantum é 1, a menos que especificado de outra forma com -c.

-c quantum

Especifique o número de linhas, quantum, após o qual o retorno de chamada de função \/expressão deve ser executado \/avaliado se especificado com -C.
variedade O nome da variável de array onde as linhas devem ser escritas. Se array for omitido, a variável padrão MAPFILE será o destino.

Notas

O nome do comando readarray pode ser usado como um apelido para o nome do comando mapfile, sem diferença na operação.

Se a opção -u for especificada, mapfile lê a partir do descritor de arquivo fd em vez da entrada padrão.

Se a matriz não for especificada, a variável padrão MAPFILE será usada como a variável da matriz de destino.

O comando mapfile não é muito portátil. Ou seja, se você deseja garantir que seu script possa ser executado em uma ampla variedade de sistemas, não é recomendado usar mapfile. É fornecido principalmente como uma conveniência. A mesma funcionalidade pode ser alcançada usando um loop de leitura, embora em geral o mapfile tenha um desempenho mais rápido.

Status de saída

O comando mapfile retorna 0 para sucesso, ou 1 se algo der errado, por exemplo, uma opção inválida é fornecida ou a variável de destino é somente leitura ou não é uma matriz.

Exemplos

O comando mapfile lê a entrada linha por linha e coloca cada linha em uma variável de array. Vamos fornecer várias linhas de entrada.

Podemos usar printf para fazer isso. É uma maneira fácil de imprimir texto com novas linhas.

Em nossa string de formato printf, podemos incluir ” n” (uma barra invertida imediatamente seguida por um n minúsculo) para criar uma nova linha. (” n” é um metacaractere, uma sequência de caracteres que representa outro caractere que não pode ser digitado literalmente, como a tecla Enter. Para obter uma lista completa de metacaracteres bash, consulte aspas em bash.)

Este comando printf imprime três linhas de texto:

printf "Line 1nLine 2nLine 3n"
 Line 1
 Line 2
 Line 3

Queremos usar mapfile para colocar cada uma dessas linhas em seu próprio elemento de um array.

Por padrão, mapfile lê a partir da entrada padrão, então você pode ficar tentado a canalizar a saída de printf para mapfile assim:

printf "Line 1nLine 2nLine 3n" | mapfile

Você esperaria que a variável de matriz padrão MAPFILE contivesse os valores dessas linhas. Mas se você verificar o valor de MAPFILE:

echo "${MAPFILE[@]}"
[a blank line]

A variável está vazia. Porque?

Cada comando em um pipeline é executado em um subshell – uma instância de bash, executado como um processo filho. Cada subshell tem seu próprio ambiente e seu próprio escopo léxico – as variáveis ​​que compõem o ambiente de cada subshell no pipeline não são transferidas para os outros. Em outras palavras, não há efeitos colaterais ambientais compartilhados de um elemento de um pipeline para o próximo. Em nosso exemplo acima, mapfile funciona corretamente e define os valores de MAPFILE, mas quando o subshell do comando termina, a variável MAPFILE desaparece.

Você pode ver isso se ecoar o valor de MAPFILE dentro de um subshell que também contém o comando mapfile, colocando ambos entre parênteses:

printf "Line 1nLine 2nLine 3n" | ( mapfile; echo "${MAPFILE[@]}" )
 Line 1
 Line 2
 Line 3

No comando acima, echo imprime todos os elementos da variável de matriz MAPFILE, separados por um espaço. O espaço aparece no início das linhas 2 e 3 por causa das novas linhas em nossos dados. Nossa subcamada explícita, expressa entre parênteses, preserva o valor de MAPFILE por tempo suficiente para que possamos ver os valores.

Podemos consertar as quebras de linha removendo-as com -t:

printf "Line 1nLine 2nLine 3n" | ( mapfile -t; echo "${MAPFILE[@]}" )
Line 1 Line 2 Line 3

(Podemos colocar as quebras de linha de volta em nossa saída se usarmos printf – faremos isso nos exemplos subsequentes.)

Portanto, mapfile está funcionando, mas a variável de array está inacessível para o shell pai. Normalmente, entretanto, você desejará que a variável MAPFILE persista para os comandos subsequentes. Você pode fazer isso com a substituição do processo.

Usando mapfile com substituição de processo

Com a substituição do processo, podemos redirecionar a saída para mapfile sem usar um pipeline.

mapfile -t < <(printf "Line 1nLine 2nLine 3")

Vejamos as partes individuais deste comando:

mapfile -t Mapfile obtém a entrada da entrada padrão e retira as novas linhas (-t) do final de cada linha. Isto é (normalmente) o que você deseja: apenas o texto da linha é armazenado em seu elemento de array, e o caractere de nova linha é descartado.
< O primeiro <é um caractere de redirecionamento. Ele espera ser seguido por um nome de arquivo ou descritor de arquivo. O conteúdo desse arquivo é redirecionado para a entrada padrão do comando anterior.

<(...)

Esses caracteres indicam substituição de processo, que retorna um descritor de arquivo. Os comandos entre parênteses são executados e sua saída é atribuída a este descritor de arquivo. Em qualquer comando bash, você pode usar a substituição de processo como um nome de arquivo.

Quando você executa o comando inteiro, mapfile lê silenciosamente nossas três linhas de texto e coloca cada linha em elementos individuais da variável de array padrão, MAPFILE.

Podemos verificar isso usando printf para imprimir os elementos do array.

printf "%s" "${MAPFILE[@]}"

O primeiro argumento, “% s”, é a string de formato printf. O segundo argumento, “${MAPFILE[@]} “, é expandido por bash. Todos os elementos (” @ “) da matriz MAPFILE são expandidos para argumentos individuais. (Para obter mais informações, consulte: Referência a elementos da matriz em bash.)

Line 1Line 2Line 3

Como você pode ver, nossas três linhas de texto são impressas lado a lado. Isso porque eliminamos as novas linhas com -t e printf não produz novas linhas por padrão.

Para especificar que printf imprima uma nova linha após cada linha, use n na string de formato:

printf "%sn" "${MAPFILE[@]}"
Line 1
Line 2
Line 3

Para acessar elementos individuais da matriz, substitua @ por um número de índice. A numeração é baseada em zero, então 0 indexa o primeiro elemento, 1 indexa o segundo, etc:

printf "%sn" "${MAPFILE[0]}"
Line 1
printf "%sn" "${MAPFILE[2]}"
Line 3

read – Leia uma linha, divida-a em palavras e atribua cada palavra a uma variável.


Like it? Share with your friends!

0
Rubem Rego

0 Comments

Your email address will not be published. Required fields are marked *