¿Cómo imprimir variables multilínea en columnas de lado a lado (bash)?

11

Tengo dos variables que contienen información de varias líneas y quiero agruparlas.

varA devoluciones

Aug 01
Aug 04
Aug 16
Aug 26

y varBvuelve

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

si imprimo ambas variables, devuelve

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

Lo que quiero hacer es lo siguiente:

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

Soy nuevo en Linux y agradecería algunos consejos, gracias.

BNairb
fuente
Incluya el código bash que utilizó en su intento de imprimir las dos variables. Es para que podamos ver lo que has hecho mal en tu intento.
Bernard Wei

Respuestas:

22

Meet paste, parte de las utilidades principales de GNU preinstaladas :

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

pastetoma archivos y no variables como entrada, por lo que utilicé bashProcess Substitution y simplemente imprimí el contenido variable con printf. El delimitador predeterminado entre columnas es TAB, puede cambiar eso con la -dopción, por ejemplo, paste -d" "para un solo carácter de espacio. Para obtener más información, pasteconsulte el manual en línea o ejecútelo info '(coreutils) paste invocation'.

postre
fuente
1
@BNairb Si esta respuesta resuelve su problema, por favor tome un momento y aceptarla haciendo clic en la marca de verificación a la izquierda. Eso marcará la pregunta como respondida y es la forma en que se agradece en los sitios de Stack Exchange.
postre
7

Si solo desea mostrar las variables de texto una al lado de la otra, @dessert tiene la solución más simple (¿la mejor?) print. Sin embargo, si desea poder manipular cada pieza individualmente, puede convertir fácilmente los vars en matrices y recorrerlo.

#!/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
fuente
3

Si desea evitar utilidades externas y hacerlo de forma nativa en el shell, puede usar readdescriptores de archivo separados / cadenas aquí para cada variable:

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

Aunque a menudo se considera una mala práctica usar el shell para el procesamiento de texto, puede excusarse en el caso de que ya tenga los datos en las variables del shell.

conductor de acero
fuente
3

Puede hacer esto con la herramienta 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

O para una sola pestaña:

pr -2 -t -s

O para un solo espacio:

pr -2 -t -s' '

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

O con columndel util-linuxpaquete:

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