Jak używać kolumny do ograniczania tabulatorów, a nie spacji?

59

Chciałbym użyć columnpolecenia Unix do sformatowania tekstu. Mam pola rozdzielone tabulatorami, ale w każdym polu są również spacje. columnograniczenia na białych spacjach (tabulatory i spacje). Jak sprawić, by kolumna używała wyłącznie tabulatorów jako separatora?

Próbowałem określić tabulator jako separator, używając:

cat myfile | column -t -s"\t"
żółw
źródło

Odpowiedzi:

82
column -t -s '\t'

oddzieli kolumny \i tznaki.

column -s \tjest taki sam jak column -s t, ponieważ odwrotny ukośnik jest interpretowany przez powłokę jako operator cytowania.

Tutaj chcesz przekazać prawdziwy znak TAB do kolumny. Z ksh93, zsh, bash, mksh, busybox sh lub FreeBSD sh:

column -ts $'\t'

Lub wprowadź prawdziwy znak tabulacji, pisząc Ctrl-V Tabw wierszu poleceń powłoki (w cudzysłowach lub poprzedzony odwrotnym ukośnikiem, ponieważ znak tabulacji jest separatorem tokenów w składni powłoki, podobnie jak spacja), lub użyj "$(printf '\t')"(te podwójne cudzysłowy potrzebne do wyłączenia split + glob operator, ponieważ znak tabulacji również ma domyślną wartość $IFS).

Stéphane Chazelas
źródło
3
Musiałem to zrobić, column -t -s $'\t'ponieważ bash wydawało się, że '\t'oznacza zarówno jedno , jak \ i drugie t, ale $'\t'oznacza dosłowną zakładkę. Bash śmierdzi
ThorSummoner
Jeśli potrzebujesz zgodności z POSIX (Panie, pomóż mi), zapoznaj się z moją odpowiedzią, która jest w dużej mierze oparta na tej fantastycznej odpowiedzi!
Nick Bull
To rozwiązanie działało dla mnie - $'\t'czyni tabulator separatorem. Ale jestem prawie pewien, że zrobię to, awk -F "\t"aby użyć tabulatora jako ogranicznika dla awk. Dlaczego to działa, a nie tutaj dla kolumny?
Mike
3

Użyłem następujących (działa tylko, jeśli twój tekst nie zawiera |):

cat myfile | tr '\t' '|' | column -t -s '|'

To po prostu zamienia karty na potoki, a następnie używa kolumny z potokami jako ograniczników.

(Zrobiłem to, ponieważ w odpowiedzi Stéphane'a nie widziałem niczego, co zadziałałoby w skorupce ryby. W przeciwnym razie odpowiedź Stéphane'a wydaje się dobra.)

Aaron Feldman
źródło
3

Dla POSIX, $'...'znany jako ucieczka ANSI-C, nie jest zdefiniowany.

Zamiast tego możesz użyć $(printf '\t'):

column -t -s "$(printf '\t')"

$(printf '\011')można użyć, ponieważ 011(ósemkowa reprezentacja dziesiętna 9) jest kodem ANSI dla znaku tabulacji w poziomie:

column -t -s "$(printf '\011')"

Jednak zobacz komentarz Stéphane'a Chazelasa poniżej, dlaczego może to nie być spójne w różnych wersjach powłoki.

Nick Bull
źródło
2
Zauważ, że POSIX nie określa, jakie jest kodowanie TAB. Nadal istnieją systemy POSIX, których kodowanie regionalne C opiera się na EBCDIC, gdzie TAB ma 5, a nie 9 jak w ASCII. Tam, gdzie to możliwe, lepiej odwoływać się do postaci po imieniu, aby uniknąć tego rodzaju problemów, jak w przypadku, "$(printf '\t')"jak pokazano w mojej odpowiedzi. Uwaga: $'...'planowane jest włączenie do następnej głównej wersji specyfikacji POSIX.
Stéphane Chazelas,
@ StéphaneChazelas jest $(printf '\t')POSIX? Dziękuję Ci!
Nick Bull
3
tak
Stéphane Chazelas,
@ StéphaneChazelas Dziękuję bardzo, zaktualizowałem swoją odpowiedź, aby uwzględnić waszą bardzo pomocną wskazówkę :)
Nick Bull
2

Służy -tdo wyboru liczby kolumn, które chcesz. Pozostawienie tego pola pustego niczego nie zmienia. Ponadto chcesz po tym spacji, -swięc wypróbuj to:

cat myfile | column -s \t

czai się
źródło
Dzięki. To jest blisko tego, czego szukam. Jednak teraz wszystkie linie są scalone w jedną linię. Jak mogę zachować każdą linię na osobnej linii?
żółw
Domyślnie columnwypełnia wiersze przed kolumnami. Możesz być zainteresowanypr
lurker