Jak korzystać z polecenia printf Bash w systemie Linux?
Opublikowany: 2022-06-25 Polecenie Bash printf
umożliwia pisanie w oknie terminala systemu Linux z lepszą kontrolą i większą liczbą opcji formatowania niż zapewnia polecenie echo
. Nawet dziwne dziwactwa printf
mogą się przydać.
Pisanie do terminala
Jest to jedna z najbardziej podstawowych części interakcji z programem. Program zapisuje coś na ekranie, a ty to czytasz. Nawet biorąc pod uwagę wywodzącą się z Uniksa i podtrzymywaną przez Linuksa konwencję programów wiersza poleceń, która jest tak zwięzła, jak to tylko możliwe – wiele z nich pisze do terminala tylko wtedy, gdy coś pójdzie nie tak. Informowanie użytkownika o tym, co się dzieje, ma się wydarzyć lub właśnie się wydarzyło, jest podstawowym elementem programowania.
Powłoka Bash ma polecenie echo
, które może zapisywać tekst w oknie terminala. Może obsługiwać zmienne i wyświetlać ich wartości, jeśli są zawarte w łańcuchu, i można go używać w skryptach lub w wierszu poleceń. Dlaczego więc printf
w ogóle istnieje? Czy echo
nie obejmuje kwestii pisania tekstu? Cóż, printf
oferuje funkcjonalność wykraczającą poza zwykłą czynność zapisywania ciągów znaków do okien terminala. Pozwala na formatowanie danych wyjściowych z dużą elastycznością i ma też inne sztuczki.
Polecenie printf
Bash jest wzorowane na funkcji printf
z języka C, ale istnieją różnice. Jeśli znasz C, musisz uważać na te różnice.
Pisanie podstawowych ciągów
Zobaczmy, jak echo
i printf
różnią się, gdy zapisują ciągi do terminala.
echo oto kilka słów
printf oto kilka słów
Polecenie echo
drukuje wszystkie słowa, ale printf
drukuje tylko pierwsze słowo. Ponadto printf
nie drukuje nowego wiersza. Dane wyjściowe są łączone bezpośrednio z wierszem poleceń. Ale po pierwsze, aby printf
wszystkie słowa, należy je zacytować.
echo oto kilka słów
printf "oto kilka słów"
Tak jest lepiej. Mamy wydrukowane wszystkie słowa, ale wciąż nie mamy nowej linii. To dlatego, że z printf
otrzymujesz nową linię tylko wtedy, gdy o nią poprosisz. To może wydawać się uciążliwe, ale pozwala zdecydować, czy uwzględnić jeden, czy nie. Aby printf
wydał nową linię, musisz dołączyć „ \n
” w swoim łańcuchu. To jest sekwencja ucieczki „nowej linii”.
echo oto kilka słów
printf "oto kilka słów\n"
Czasami użyjesz nowej linii, a czasami nie. Oto przypadek, w którym jedna instrukcja printf
używa nowej linii, a druga nie.
printf "Jak to zrobić " && printf "Geek\n"
Ponieważ pierwszy printf
nie drukuje nowego wiersza, dane wyjściowe drugiego printf
są umieszczane bezpośrednio po „How-To” iw tym samym wierszu. Drugi printf
używa \n
do wypisania nowej linii. Dzięki temu wiersz polecenia pojawi się w wierszu poniżej drukowanego tekstu.
POWIĄZANE: Jak przetwarzać wiersz po wierszu w skrypcie Linux Bash
Inne postacie ucieczki
Oto kilka innych znaków ucieczki, których możesz użyć. Widziałeś już „ \n
” w akcji.
- \n : Przechodzi w dół do nowej linii.
- \r : Drukuje powrót karetki. Spowoduje to wysłanie kursora wyjściowego z powrotem na początek bieżącego wiersza.
- \t : Drukuje znak tabulacji.
- \v : drukuje pionową spację tabulacji.
- \\ : Drukuje znak odwrotnego ukośnika.
- \” : Drukuje znak cudzysłowu.
- \b : Drukuje znak cofania.
Znak zmiany znaczenia powrotu karetki przesuwa kursor z powrotem na początek bieżącego wiersza.
printf "Miód jest źródłem wszelkiego zła\rPieniądze\n"
Polecenie printf
przetwarza dane wejściowe od lewej do prawej. Ciąg jest drukowany jako zwykły tekst, dopóki printf
nie napotka znaku ucieczki „ \r
”. Kursor wyjściowy jest cofany na początek bieżącego wiersza.
Przetwarzanie ciągu zostanie wznowione z literą bezpośrednio za znakiem „ \r
”. Przetworzenie reszty powoduje, że printf
drukuje „Pieniądze”, zastępując słowo „Miód”.
Znak cudzysłowu „ "
” jest używany do cytowania ciągów, a znak odwrotnego ukośnika „ \
” oznacza sekwencje specjalne. Jeśli chcesz wydrukować te znaki, musisz je zmienić za pomocą odwrotnego ukośnika. To mówi printf
, aby traktował je jako znaki dosłowne.
printf "To jest \tTab, to jest cudzysłów \", a to \\ to ukośnik odwrotny\n"
Korzystanie ze zmiennych
Używanie zmiennych z printf
jest bardzo podobne do używania ich z echo
. Aby dołączyć zmienną, taką jak ta zmienna środowiskowa, poprzedź ją jak zwykle znakiem dolara „ $
”.
printf "Katalog domowy: $HOME\n"
POWIĄZANE: Jak pracować ze zmiennymi w Bash
Ciągi formatujące
Ciągi formatujące to ciągi, które definiują format danych wyjściowych. Podaj tekst i inne wartości jako argumenty dla ciągu formatu, na którym ma działać.
Ciąg formatu może zawierać tekst, sekwencje ucieczki i specyfikatory formatu . Specyfikatory formatu informują printf
, jakiego typu argumentu ma oczekiwać, takiego jak łańcuchy, liczby całkowite lub znaki.
To są najczęstsze specyfikatory formatu. Wszystkie są poprzedzone znakiem procentu „ %
”. Aby wydrukować znak procentu, użyj razem dwóch znaków procentu „ %%
”.
- %s : Drukuje ciąg.
- %c : Drukuje pojedynczy znak.
- %d : drukuje liczbę całkowitą.
- %f : drukuje liczbę zmiennoprzecinkową.
- %u : Drukuje liczbę całkowitą bez znaku.
- %o : Drukuje wartość w postaci ósemkowej.
- %x : Drukuje wartość szesnastkowo, małymi literami.
- %X : Drukuje wartość w systemie szesnastkowym, pisanym wielkimi literami.
- %e : Drukuje liczbę zmiennoprzecinkową w notacji naukowej, małymi literami.
- %E : Drukuje liczbę zmiennoprzecinkową w notacji naukowej, pisaną wielkimi literami.
- %% : Drukuje symbol procentu „%”.
printf "Jak to zrobić %s\n" "Geek"
printf "%s%s %s\n" "Jak" "-Do" "Geek"
Ciąg formatu w pierwszym poleceniu zawiera własny tekst. Przekazujemy ciąg „Geek” jako argument do printf
. Jest dopasowywany i drukowany przez specyfikator formatu „ %s
”. Zauważ, że między ciągiem formatu a ciągiem argumentu jest tylko spacja. W C potrzebny byłby przecinek, aby je oddzielić, ale w wersji printf
w Bash wystarczy użycie spacji.
Drugi ciąg formatu zawiera tylko specyfikatory formatu i sekwencję ucieczki nowego wiersza. Trzy argumenty ciągu są zużywane po kolei przez każdy ze specyfikatorów formatu „ %s
”. Ponownie, w C musisz umieścić przecinek między każdym argumentem, ale printf
Bash pozwala nam o tym zapomnieć.
Aby wydrukować różne typy argumentów, wystarczy użyć odpowiedniego specyfikatora formatu. Oto procedura szybkiej konwersji liczb zbudowana przy użyciu printf
. Wydrukujemy wartość 15 w notacji dziesiętnej, ósemkowej i szesnastkowej.
printf "Grudzień: %d\nPaździernik: %o\nHeks: %x\n" 15 15 15
Przytnijmy to nieco, aby przykład był mniej zaśmiecony.
printf "Hex: %x\n" 15
Większość z nas jest przyzwyczajona do wyświetlania wartości szesnastkowych pisanych wielkimi literami i wartości mniejszych niż 0x10 z wiodącym zerem. Możemy to osiągnąć, używając specyfikatora formatu szesnastkowego pisanego wielkimi literami „ %X
” i umieszczając specyfikator szerokości między znakiem procentu „ %
” a znakiem „ X
”.
Mówi to printf
o szerokości pola, w którym powinien zostać wydrukowany argument. Pole jest dopełniane spacjami. W tym formacie wartości dwucyfrowe byłyby drukowane bez żadnego dopełnienia.
printf "Hex: %2X\n" 15
Otrzymujemy teraz wielką wartość, wydrukowaną ze spacją wiodącą. Możemy sprawić, by printf
wypełnił pole zerami zamiast spacjami, umieszczając zero przed tymi dwoma:
printf "Hex: %02X\n" 15
Specyfikator dokładności umożliwia ustawienie liczby miejsc dziesiętnych do uwzględnienia w danych wyjściowych.
printf "Punkt zmiennoprzecinkowy: %08.3f\n" 9.243546
Ułatwia to tworzenie tabel wyników ze starannie wyrównanym wydrukiem. To następne polecenie demonstruje również inne dziwactwa Bash printf
. Jeśli jest więcej argumentów niż specyfikatorów formatu, argumenty są podawane do ciągu formatu w partiach, dopóki wszystkie argumenty nie zostaną zużyte. Wielkość partii, która jest przetwarzana jednocześnie, to liczba specyfikatorów formatu w ciągu formatu. W C, dodatkowe argumenty w wywołaniach funkcji printf
są ignorowane.
printf "Pływ: %8.3f\n" 9.243546 23.665 8.0021
Specyfikatorów szerokości i precyzji można używać również z ciągami. To polecenie drukuje łańcuchy w polu o szerokości 10 znaków.
printf "%10s %d\n" "płaszcze" 7 "buty" 22 "Parasole" 3
Domyślnie wartości w swoich polach są wyrównywane do prawej. Aby wyrównać je do lewej, użyj znaku minus „ -
” bezpośrednio za znakiem procentu „ %
”.
printf "%-10s %d" "płaszcze" 7 "buty" 22 "Parasole" 3
Specyfikatora dokładności można użyć do ustawienia maksymalnej liczby drukowanych znaków. Używamy znaków dwukropka „ :
”, aby pokazać granice pola szerokości. Nie tak, jak skrócono słowo „Parasole”.
printf ":%10.6s:\n" "płaszcze" "buty" "Parasole"
printf ":%-10.6s:\n" "płaszcze" "buty" "Parasole"
Specyfikator szerokości może być nawet przekazany jako argument . Użyj gwiazdki „ *
” zamiast specyfikatora liczbowego i przekaż szerokość jako argument będący liczbą całkowitą.
printf "%*s\n" 20 "Skrajnie w prawo" 12 "Środek" 5 "Skrajnie na lewo"
Inne sztuczki i dziwactwa
Specyfikatory formatu wewnątrz ciągu formatu będą działać z wartościami odpowiedniego typu, niezależnie od tego, czy są one podane w wierszu polecenia jako zwykłe argumenty, czy też są generowane jako dane wyjściowe wyrażenia .
To wypisuje sumę dwóch liczb:
printf "23+32=%d\n" $((23+32))
To polecenie drukuje liczbę katalogów w bieżącym katalogu roboczym:
printf "Istnieje %d katalogów\n" $(ls -d */ | wc -l)
To polecenie printf
drukuje ciąg znaków zwrócony z wywołania innego polecenia.
printf "Bieżący użytkownik: %s\n" $(whoami)
Jeśli specyfikator formatu łańcucha „ %s
” nie jest dostarczany z argumentem, to printf
nic nie wypisuje.
printf "Jeden: %s dwa: %s\n" "Alfa"
Jeśli specyfikatorowi formatu ciągu „ %s
” przez pomyłkę podano wartość liczbową, drukuje ją tak, jakby był ciągiem i nie narzeka. Nie próbuj tego z C printf
— wydarzą się bardzo złe rzeczy. Twój program prawdopodobnie ulegnie awarii. Ale printf
Bash radzi sobie z tym bez narzekania.
printf "Jeden: %s dwa: %s\n" "Alfa" 777
Jeśli specyfikator formatu liczb całkowitych „ %d
” nie otrzyma żadnego argumentu, wypisze zero.
printf "Liczba całkowita: %d\n"
Jeśli specyfikator formatu liczb całkowitych „ %d
” przez pomyłkę otrzyma argument ciągu, Bash wypisze komunikat o błędzie, a printf
wypisze zero.
printf "Liczba całkowita: %d\n" "Siedem"
Niezręczne symbole można generować, używając ich numeru Unicode lub „punktu kodowego”. Są one pomijane przy użyciu litery „u”, po której następuje ich wartość Unicode.
printf "Symbol euro: \u20AC\n"
Aby dołączyć sekwencje specjalne do ciągów argumentów , musisz użyć specyfikatora formatu „ %b
” w ciągu formatu, a nie specyfikatora formatu ciągu „ %s
”.
printf "%s" "\u20AC\n"
printf "%b" "\u20AC\n"
Pierwsza instrukcja printf
nie przetwarza wartości Unicode i nie rozpoznaje sekwencji ucieczki nowego wiersza. Druga instrukcja printf
używa specyfikatora formatu „ %b
”. To poprawnie obsługuje znak Unicode i drukowany jest nowy wiersz.
POWIĄZANE: Czym są kodowania znaków, takie jak ANSI i Unicode, i czym się różnią?
Konie na kursy
Czasami wszystko, co musisz zrobić, to echo
jakiś tekst w oknie terminala. Ale kiedy musisz zastosować pozycjonowanie i formatowanie, printf
jest właściwym narzędziem do tego zadania.
printf "%b" "Tha-" "tha-" "tha-" "to wszystko.\n"