Znaki tabulacji echa w skrypcie bash


313

Jak wyświetlić echo jednego lub więcej znaków tabulacji za pomocą skryptu bash? Kiedy uruchamiam ten kod

res='       'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

rozumiem

res=[ x] # that is [<space>x]

Odpowiedzi:


529
echo -e ' \t '

wyświetli echo „spacja tabulacja spacja nowa linia” ( -eoznacza „włącz interpretację znaków ukośnika odwrotnego”):

$ echo -e ' \t ' | hexdump -C
00000000  20 09 20 0a                                       | . .|

Dzięki Johannes. Pomogłeś mi znaleźć to rozwiązanie: res = '\ t \ t'x; echo -e '[' $ res ']'
kalyanji

2
Czy wiesz, dlaczego echo -enie działa z Makefiles?
dma_k 17.10.10

23
To dlatego, że echo -enie jest POSIX i makewywołania, /bin/shktóre zwykle nie są używane przez program, używają interaktywnie i zwykle nie zostały -ezaimplementowane. Aby zapewnić przenośność, użyj printf '\t'zamiast tego.
Jo So

W Darwin (macOS) manstrona echopolecenia nie wspomina o tej opcji -e. Ta opcja jest jednak akceptowana.
ePi272314

75

Użyj printf, nie echo.

Istnieje wiele różnych wersji echopolecenia. Istnieje /bin/echo(która może, ale nie musi być wersja GNU Coreutils, w zależności od systemu), a echopolecenie jest wbudowane w większość powłok. Różne wersje mają różne sposoby (lub brak możliwości) określenia lub wyłączenia znaków zmiany znaczenia dla znaków kontrolnych.

printfz drugiej strony ma znacznie mniejszą zmienność. Zwykle może istnieć jako polecenie /bin/printfi jest wbudowany w niektóre powłoki (bash i zsh to mają, tcsh i ksh nie), ale różne wersje są znacznie bardziej do siebie podobne niż różne wersje echo. I nie musisz pamiętać opcji wiersza poleceń (z kilkoma wyjątkami; GNU Coreutils printf akceptuje --versioni --help, a wbudowany bash printf akceptuje-v var przechowywanie danych wyjściowych w zmiennej).

Na przykład:

res='           'x # res = "\t\tx"
printf '%s\n' "[$res]"

A teraz nadszedł czas, żebym przyznał, że echozadziała równie dobrze w przypadku przykładu, o który pytasz; wystarczy wstawić podwójny cudzysłów wokół argumentu:

echo "[$res]"

jak napisał kmkaplan (dwa i pół roku temu, właśnie to zauważyłem!). Problem z oryginalnymi poleceniami:

res='           'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

nie jest z echo; polega na tym, że skorupa zastąpiła zakładkę spacją, zanim echoją zobaczyła.

echonadaje się do prostych wyników, takich jak echo hello world, ale powinieneś używać, printfgdy chcesz zrobić coś bardziej złożonego. Ty może dostać echosię do pracy, ale otrzymany kod może zawieść po uruchomieniu go z innej echorealizacji lub innej powłoki.


1
Podobał mi się ten, pozwala mi korzystać z wiedzy o printf i wszystkich specyfikatorach formatu.
Arun,

@JezenThomas: Nie ma większego szacunku, ponieważ odpowiada na pytanie w inny sposób niż wymagany. Pytanie wyraźnie wymienia echo, a echo nie jest czasownikiem, ale poleceniem.
Paulo Neves

@PauloNeves: Powiedziałbym, że jest używany jako czasownik w pytaniu: „Jak mogę echa jednej lub więcej znaków tabulacji za pomocą skryptu bash?”
Keith Thompson

34

Umieść ciąg między podwójnymi cudzysłowami:

echo "[$res]"

1
to samo tutaj - tego właśnie próbowałem. -e działało dobrze
froderik

2
@kmkaplan Działa dla mnie w Zsh - kończy się niepowodzeniem w bash
Kal

34

Możesz także spróbować:

echo Hello$'\t'world.

4
+1 za bardziej ogólne rozwiązanie. Używam bash od lat i właśnie się tego nauczyłem!
Aryeh Leib Taurog

Jest to znacznie bardziej ogólna niż zaakceptowana odpowiedź, ponieważ można jej używać bez echa.
jwan


16

Ze strony podręcznika użytkownika bash:

Słowa w postaci $ „string” są traktowane specjalnie. Słowo rozwija się do łańcucha znaków, a znaki specjalne z odwrotnym ukośnikiem są zastępowane zgodnie ze standardem ANSI C.

Możesz to zrobić:

echo $'hello\tworld'

Dlaczego działa to na cli, ale nie w skrypcie bash?
Freek

13

Za pomocą klawiszy verbatim, ^V( CTRL+V, C-v, cokolwiek ).

Podczas pisania ^Vw terminalu (lub w większości edytorów uniksowych) następujący znak jest pobierany dosłownie . Możesz użyć tego do wpisania literowego znaku tabulacji wewnątrz echa łańcucha.

Coś jak następujące prace:

echo "^V<tab>"     # CTRL+V, TAB

Dokumenty Bash ( qv , „quoted-insert”)

quoted-insert (Cq, Cv) Dodaj kolejny wpisany znak do wiersza dosłownie. Oto jak wstawić sekwencje klawiszy, na przykład Cq.

uwaga dodatkowa: zgodnie z tym ALT+TAB powinniśmy zrobić to samo, ale wszyscy związaliśmy tę sekwencję z przełączaniem okien, więc nie możemy jej użyć

tab-insert (M-TAB) Wstaw znak tabulacji.

-

Uwaga: możesz używać tej strategii z różnego rodzaju nietypowymi postaciami. Jak zwrot karetki:

echo "^V^M"        # CTRL+V, CTRL+M

Wynika to z faktu, że znak powrotu karetki to ASCII 13, a M to 13 litera alfabetu, więc kiedy piszesz ^M, otrzymujesz 13 znak ASCII. Możesz zobaczyć to w akcji, używając ls^Mpustego monitu, który wstawi znak powrotu karetki, powodując, że będzie on działał tak samo, jak trafiłeś return. Kiedy te znaki są normalnie interpretowane, dosłownie dostajesz dosłowny znak.


1
Żałuję, że nie mogę dać więcej głosów na ten temat. W tym przypadku nie chciałem używać -e, a to działa świetnie. Dzięki!
Aaron R.

„... większość edytorów Uniksa”? Próbowałem wprowadzić to zarówno z vi, jak i emacsem, ale nie przyniosło to pożądanych rezultatów.
GreenMatt

To takie fajne! I uratowałem mój dzień, gdy próbowałem użyć grepdo łapania linii zawierających tabznaki.
Joël


2

Jeśli chcesz użyć echo "a\tb"skryptu, uruchom skrypt jako:

# sh -e myscript.sh

Alternatywnie możesz dać myscript.sh uprawnienie do wykonywania, a następnie uruchomić skrypt.

# chmod +x myscript.sh
# ./myscript.sh

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.