Come stampare variabili multilinea in colonne affiancate in bash?


12

Ho due variabili che contengono informazioni multilinea e voglio metterle in colonna.

varA ritorna

Aug 01
Aug 04
Aug 16
Aug 26

e varBritorna

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

se stampo entrambe le variabili, ritorna

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

Quello che voglio fare è il seguente:

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

Sono nuovo nell'uso di Linux e apprezzerei alcuni consigli.


Includi il codice bash che hai usato nel tentativo di stampare le due variabili. È così che possiamo vedere cosa hai fatto di sbagliato nel tuo tentativo.
Bernard Wei,

Risposte:


22

Meet paste, parte delle utility core GNU preinstallate :

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

pasteaccetta i file e non le variabili come input, quindi ho usato bashProcess Substitution e ho appena stampato il contenuto della variabile printf. Il delimitatore predefinito tra le colonne è TAB, è possibile modificarlo con l' -dopzione, ad esempio paste -d" "per un singolo carattere di spazio. Per saperne di più, dai pasteun'occhiata al manuale online o corri info '(coreutils) paste invocation'.


1
@BNairb Se questa risposta ha risolto il problema, prenditi un momento e accettalo facendo clic sul segno di spunta a sinistra. Questo segnerà la domanda come risposta ed è il modo in cui i ringraziamenti sono espressi sui siti di Stack Exchange.
dessert,

7

Se vuoi semplicemente visualizzare le variabili di testo fianco a fianco, @dessert ha la soluzione più semplice (migliore?) Che utilizza print. Tuttavia, se si desidera essere in grado di manipolare ogni singolo pezzo, è possibile invece convertire facilmente i var in array e passare in rassegna quello.

#!/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"

4

Puoi farlo con lo strumento 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

Risultato:

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

O per scheda singola:

pr -2 -t -s

O per spazio singolo:

pr -2 -t -s' '

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

O con columndal util-linuxpacchetto:

column -c 20 <<eof
$varA
$varB
eof

3

Se si desidera evitare utility esterne e farlo nativamente nella shell, è possibile utilizzare readcon descrittori di file separati / stringhe qui per ogni variabile:

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

Sebbene sia spesso considerato una cattiva pratica usare la shell per l'elaborazione del testo, potrebbe essere scusato nel caso in cui tu abbia già i dati nelle variabili della shell.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.