Jak korzystać z polecenia printf Bash w systemie Linux?

Opublikowany: 2022-06-25
Terminal Linux na niebieskim tle.
fatmawati achmad zaenuri/Shutterstock.com

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.

Jak korzystać z polecenia Echo w systemie Linux
POWIĄZANE Jak korzystać z polecenia Echo w systemie Linux

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 

Używanie echa i printf z niecytowanymi słowami

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" 

Używanie echa i printf z cytowanymi słowami

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" 

Używanie echa i printf z cytowanymi słowami i znakiem nowej linii

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" 

Używanie dwóch printfs do utworzenia jednej linii tekstu

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" 

Używanie znaku powrotu karetki, aby przejść z powrotem na początek wiersza

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" 

Uciekające postacie, by były traktowane dosłownie

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" 

Używanie printf ze zmienną środowiskową

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" 

Pokazywanie printf akceptujących "zbyt wiele" argumentów

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 

używanie printf do drukowania wartości liczbowych w różnych notacjach podstawowych

Przytnijmy to nieco, aby przykład był mniej zaśmiecony.

 printf "Hex: %x\n" 15 

Drukowanie wartości szesnastkowej

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 

drukowanie wartości szesnastkowej pisanej wielkimi literami w polu o szerokości 2 znaków

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 

drukowanie wartości szesnastkowej wielkimi literami w polu o szerokości 2 znaków uzupełnionym zerami

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żywanie modyfikatorów szerokości i precyzji z liczbą zmiennoprzecinkową

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 

Używanie modyfikatorów szerokości i precyzji do stworzenia schludnego stołu

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 

Używanie modyfikatora szerokości ze stringami

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 

Korzystanie z wyrównanego do lewej specyfikatora szerokości z ciągami

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" 

Używanie modyfikatora precyzji do ograniczenia liczby znaków, które są drukowane z ciągu

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" 

Przekazywanie specyfikatora szerokości jako argumentu do printf

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)) 

Drukowanie sumy dwóch liczb

To polecenie drukuje liczbę katalogów w bieżącym katalogu roboczym:

 printf "Istnieje %d katalogów\n" $(ls -d */ | wc -l) 

Liczenie katalogów z printf

To polecenie printf drukuje ciąg znaków zwrócony z wywołania innego polecenia.

 printf "Bieżący użytkownik: %s\n" $(whoami) 

Drukowanie danych wyjściowych z innego polecenia

Jeśli specyfikator formatu łańcucha „ %s ” nie jest dostarczany z argumentem, to printf nic nie wypisuje.

 printf "Jeden: %s dwa: %s\n" "Alfa" 

Jak printf radzi sobie z brakującymi argumentami ciągu?

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 

Jak printf po cichu akceptuje liczby całkowite jako wartości łańcuchowe?

Jeśli specyfikator formatu liczb całkowitych „ %d ” nie otrzyma żadnego argumentu, wypisze zero.

 printf "Liczba całkowita: %d\n" 

Jak printf radzi sobie z brakującymi argumentami całkowitymi?

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" 

Jak printf traktuje łańcuchy, które są dostarczane zamiast argumentów całkowitych?

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" 

Drukowanie wartości Unicode ze znakami ucieczki

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" 

Używanie specyfikatora formatu %b do obsługi sekwencji specjalnych w argumentach łańcuchowych

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"