Як надрукувати багаторядкові змінні в стовпчиках стовпчиків в bash?


12

У мене є дві змінні, які містять багато рядкову інформацію, і я хочу їх розміщувати в стовпцях.

varA повертає

Aug 01
Aug 04
Aug 16
Aug 26

і varBповертається

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

якщо я надрукую обидві змінні, вона повернеться

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

Я хочу зробити таке:

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

Я новачок у використанні Linux, і я буду вдячний поради.


Будь ласка, включіть bash-код, який ви використовували при спробі друку двох змінних. Це так, що ми можемо побачити, що ви зробили неправильно у своїй спробі.
Бернард Вей

Відповіді:


22

Знайомтесь paste, частина попередньо встановлених основних програм GNU :

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

pasteприймає файли, а не змінні як вхідні дані, тому я використав bashProcess Substitution і просто надрукував вміст змінної printf. Розмежувач за замовчуванням між стовпцями - це TABви можете змінити за допомогою -dпараметра, наприклад, paste -d" "для одного символу пробілу. Щоб дізнатися більше про pasteте, ознайомтеся з онлайн-посібником або запустіть info '(coreutils) paste invocation'.


1
@BNairb Якщо ця відповідь вирішила вашу проблему, будь-ласка, знайдіть хвилинку та прийміть її , натиснувши на галочку зліва. Це означатиме відповідь на питання і спосіб висловлення подяки на сайтах Stack Exchange.
десерт

7

Якщо ви просто хочете просто відобразити текстові змінні поряд, у @dessert є найпростіше (найкраще?) Рішення з використанням print. Однак якщо ви хочете мати можливість маніпулювати кожною деталлю окремо, ви можете замість цього перетворити vars в масиви і пройти цикл через це.

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

Це можна зробити за допомогою інструмента 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

Результат:

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

Або для однієї вкладки:

pr -2 -t -s

Або для одного простору:

pr -2 -t -s' '

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

Або з columnз util-linuxпакета:

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

3

Якщо ви хочете уникнути зовнішніх утиліт та робити це споконвічно в оболонці, ви можете використовувати readокремі дескриптори файлів / тут рядки для кожної змінної:

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

Хоча часто вважається поганою практикою використання оболонки для обробки тексту, це може бути виправданням у випадку, якщо ви вже маєте дані в змінних оболонок.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.