Próbuję wydrukować kilka linii w wielu kolumnach o szerokości 30 znaków:

#!/bin/bash
chars_width=15
full_string="a\\nb\\nc\\nd"
number_of_columns=$(( $(tput cols) / $chars_width ))

for ((i = 0; i < number_of_columns; i++)); do
    formatting_string="$formatting_string%%-"$chars_width"s "
done

echo "$full_string" | xargs -L $number_of_columns | \
    while read -r values
    do
        printf "$formatting_string\\n" $values
    done
exit

Biegając to, spodziewałbym się, że zostanie nagrany:

a              b              c              d

Ale wynika:

%-15s %-15s %-15s %-15s

Jak umieścić moje dynamicznie budowane reguły formatowania printf do użycia?

0
user 1 marzec 2019, 18:19

2 odpowiedzi

Najlepsza odpowiedź

Użyj pojedynczych znaków "%" w ciągu swojego formatu. Uciekłeś ich, więc nic nie zostaje podstawione.

3
ewindes 1 marzec 2019, 15:27

Ile zaufasz twoich danych? Możesz pozwolić, aby komenda parsera pasowała dodatkową białąawkę, w cenie pewnego ryzyka.

$: full_string=$'a\nb\nc\nd'
$: printf %-15s $full_string $'\n'
a              b              c              d

Jeśli Twoje dane znajdują się w pliku ...

$: r=( $(<file) )
$: printf %-15s "${r[@]}" $'\n'
a              b              c              d

Lub nawet

$: printf %-15s $(<file) $'\n'
a              b              c              d

Nie widzisz, że nowa linia została również wydrukowana w 15-szerokim polu, więc na końcu linii jest wiele przestrzeni na końcu linii.

Uwaga Te ponowne wykorzystanie pojedynczego ciąg formatowania (który był wystarczająco prosty, nie cytuję, ale zwykle powinieneś).

Umieszczanie cytatów w niewłaściwych miejscach spowodowałoby problemy ...

$:  printf %-15s "$(<file)" $'\n'
a
b
c
d

Otrzymasz ten sam wynik

$: printf %-15s "$full_string" $'\n'

Ogólnie, ty chce cytaty, ale przydatne rzeczy można zrobić, twórczo pozostawiając je i pozwalając parserowi manipulować białym znakiem. Po prostu bądź świadomy tego, co dostajesz. Jeśli w jednym z tych pól jest wbudowany biały zakład, wszystkie zakłady są wyłączone.

Dużo ten sam zestaw zastrzeżeń dotyczy samego formatu.

$: f="%-15s %5s"
$: printf $f $x $'\n' # oops!
%5s            a              b              c              d
$: printf "$f" $x $'\n'
a                   bc                   d

Więc możesz dynamicznie tworzyć różne formaty, jeśli chcesz, i po prostu zacytuj zmienną w podwójnych cytatach, aby przenikał "poprawnie". Jak zawsze przetestuj.

1
Paul Hodges 1 marzec 2019, 16:46