Como imprimir variáveis ​​de várias linhas em colunas lado a lado (bash)?

11

Eu tenho duas variáveis ​​que contêm informações de várias linhas e eu quero colocá-las em coluna.

varA retorna

Aug 01
Aug 04
Aug 16
Aug 26

e varBretorna

04:25
07:28
03:39
10:06

se eu imprimir as duas variáveis, ele retornará

Aug01
Aug04
Aug16
Aug26
04:25
07:28
03:39
10:06

O que eu quero fazer é o seguinte:

Aug01 04:25
Aug04 07:28
Aug16 03:39
Aug26 10:06

Eu sou novo no Linux e gostaria de receber alguns conselhos, obrigado.

BNairb
fonte
Inclua o código bash que você usou na tentativa de imprimir as duas variáveis. É para que possamos ver o que você fez de errado em sua tentativa.
Bernard Wei

Respostas:

22

Conheça paste, parte dos utilitários principais do GNU pré-instalados :

$ paste <(printf %s "$varA") <(printf %s "$varB")
Aug 01  04:25
Aug 04  07:28
Aug 16  03:39
Aug 26  10:06

pasteusa arquivos e não variáveis ​​como entrada, então usei bashProcess Substitution e apenas imprimi o conteúdo da variável printf. O delimitador padrão entre colunas é que TABvocê pode alterar isso com a -dopção, por exemplo, paste -d" "para um único caractere de espaço. Para saber mais paste, consulte o manual on - line ou execute info '(coreutils) paste invocation'.

sobremesa
fonte
1
@BNairb Se esta resposta resolveu seu problema, reserve um momento e aceite-o clicando na marca de seleção à esquerda. Isso marcará a pergunta como respondida e é assim que os agradecimentos são expressos nos sites do Stack Exchange.
dessert
7

Se você deseja apenas exibir as variáveis ​​de texto lado a lado, o @dessert possui a solução mais simples (melhor?) print. No entanto, se você quiser manipular cada peça individualmente, poderá facilmente converter os vars em matrizes e percorrer isso.

#!/bin/bash

# declare the multi-line variables
var1="1
2
3
4"
var2="a
b
c
d"

# backup internal field separator to be safe
IFSave=$IFS

# set IFS to newline so vars will use newline to split into array
IFS=$'\n'

# split variables into array
foo=($var1)
bar=($var2)

#restore IFS to original value to be safe
IFS=$IFSave

# loop array foo, and cross reference key in array bar
for i in "${!foo[@]}"; do 
  printf "${foo[$i]} : ${bar[$i]}\n"
done

# you can allso now print single corresponding lines:
line=3

let id=$line-1 # arrays start at 0, so need to remove one

printf "\nPrinting line number $line\n"
printf "${foo[$id]} : ${bar[$id]}\n"
Joshua Besneatte
fonte
3

Se você quiser evitar utilitários externos e fazê-lo nativamente no shell, poderá usar readdescritores de arquivos separados / strings here para cada variável:

while IFS= read -r -u3 a && read -r -u4 b; do 
  printf '%s\t%s\n' "$a" "$b"
done 3<<<"$varA" 4<<<"$varB"
Aug 01  04:25
Aug 04  07:28
Aug 16  03:39
Aug 26  10:06

Embora muitas vezes seja considerado uma má prática usar o shell para processamento de texto, pode ser desculpado se você já tiver os dados em variáveis ​​do shell.

chave de aço
fonte
3

Você pode fazer isso com a ferramenta POSIX pr:

varA='Aug 01
Aug 04
Aug 16
Aug 26'
varB='04:25
07:28
03:39
10:06'
pr -2 -t <<eof
$varA
$varB
eof

Resultado:

Aug 01                              04:25
Aug 04                              07:28
Aug 16                              03:39
Aug 26                              10:06

Ou para uma única guia:

pr -2 -t -s

Ou para espaço único:

pr -2 -t -s' '

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pr.html

Ou com columndo util-linuxpacote:

column -c 20 <<eof
$varA
$varB
eof
Steven Penny
fonte