Mam dwa pliki tekstowe. Pierwszy ma treść:
Languages
Recursively enumerable
Regular
podczas gdy drugi ma treść:
Minimal automaton
Turing machine
Finite
Chcę połączyć je w jeden plik pod względem kolumn. Więc próbowałem, paste 1 2
a jego wynik to:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Chciałbym jednak dobrze wyrównać kolumny, takie jak
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Zastanawiałem się, czy można to osiągnąć bez ręcznej obsługi?
Dodany:
Oto inny przykład, w którym metoda Bruce'a prawie ją przybiła, z wyjątkiem niewielkiego przesunięcia, o które zastanawiam się dlaczego?
$ cat 1
Chomsky hierarchy
Type-0
—
$ cat 2
Grammars
Unrestricted
$ paste 1 2 | pr -t -e20
Chomsky hierarchy Grammars
Type-0 Unrestricted
— (no common name)
pr
iexpand
...columns
unika tego problemu.➀ unicode may render oddly
but the column count is ok
zdecydowanie nie nie dotyczywc-paste-pr
iwc-paste-pr
oni pokazują różnice w liczbie kolumn. Inne są w porządku.pr
wielobajt znaki w bieżącym locale (zwykle UTF8).Odpowiedzi:
Potrzebujesz tylko
column
polecenia i powiedz mu, aby używało tabulatorów do oddzielania kolumnAby rozwiązać problem kontrowersji związanych z „pustą komórką”, potrzebujemy tylko
-n
opcjicolumn
:Moja strona podręcznika wskazuje, że
-n
jest to „rozszerzenie Debian GNU / Linux”. Mój system Fedora nie wykazuje problemu pustych komórek: wydaje się, że pochodzi on z BSD, a strona podręcznika mówi: „Wersja 2.23 zmieniła opcję -s, aby nie była chciwa”źródło
column
oczywiście; jak oczywiste (z perspektywy czasu) +1 ... Dzięki ...column -s $'\t' -t
ignoruje puste komórki , w wyniku czego wszystkie kolejne komórki po prawej stronie (w tym wierszu) przesuwają się w lewo; tj. w wyniku pustej linii w pliku lub jej krótszej ... :(Szukasz poręcznego
pr
polecenia dandy :„-E24” to „rozwiń tabulacje do 24 spacji”. Na szczęście
paste
umieszcza znak tabulacji między kolumnami, więcpr
można go rozwinąć. Wybrałem 24, licząc znaki w „Rekurencyjnie wyliczalne” i dodając 2.źródło
expand
polecenia bezpośrednio:paste file1 file2 | expand -t 24
?sed
więc jest jeden proces, który nie działa. Używapr
starożytnego polecenia, datowanego na dni Uniksa SysV, tak myślę, więc może istnieć przy większej liczbie instalacji niżexpand
. Krótko mówiąc, to tylko stara szkoła.Aktualizacja : tutaj jest o wiele prostszy skrypt (ten na końcu pytania) dla danych tabelarycznych. Po prostu przekaż do niego nazwę pliku, tak jak chcesz
paste
... Służyhtml
do tworzenia ramki, więc można ją modyfikować. Zachowuje wiele spacji, a wyrównanie kolumny jest zachowywane, gdy napotka znaki Unicode. Jednak sposób, w jaki redaktor lub przeglądający renderuje Unicode, to zupełnie inna sprawa ...---
Streszczenie narzędzi przedstawionych w odpowiedziach (jak dotąd).
Przyjrzałem się im z bliska; oto co znalazłem:
paste
# To narzędzie jest wspólne dla wszystkich dotychczas prezentowanych odpowiedzi # Może obsługiwać wiele plików; dlatego wiele kolumn ... Dobrze! # Określa każdą kolumnę tabulatorem ... Dobrze. # Dane wyjściowe nie są zestawione w tabelach.Wszystkie poniższe narzędzia usuwają ten ogranicznik! ... Źle, jeśli potrzebujesz ogranicznika.
column
# Usuwa ogranicznik Tab, więc identyfikacja pola jest oparta wyłącznie na kolumnach, które wydają się całkiem dobrze obsługiwać .. Nie zauważyłem niczego złego ... # Poza brakiem unikalnego ogranicznika, działa dobrze!expand
# Ma tylko ustawienie pojedynczej tabulacji, więc jest nieprzewidywalny poza 2 kolumnami # Wyrównanie kolumn nie jest dokładne przy obsłudze Unicode, i usuwa separator Tab, więc identyfikacja pola odbywa się wyłącznie na podstawie wyrównania kolumnpr
# Ma tylko ustawienie jednej karty, więc jest nieprzewidywalny poza 2 kolumnami. # Wyrównanie kolumn nie jest dokładne podczas obsługi Unicode i usuwa separator Tab, więc identyfikacja pola odbywa się wyłącznie na podstawie wyrównania kolumnDla mnie
column
to oczywiste najlepsze rozwiązanie jako linijka .. Chcesz separator lub tablicę ASCII-art swoich plików, czytaj dalej, w przeciwnym razie ...columns
jest całkiem dobra :) ...Oto skrypt, który pobiera dowolną liczbę plików i tworzy tabelaryczną prezentację ASCII-art. (Pamiętaj, że Unicode może nie renderować oczekiwanej szerokości, np. ௵, która jest pojedynczym znakiem. Jest to całkiem inna kolumna liczby są niepoprawne, jak ma to miejsce w przypadku niektórych narzędzi wymienionych powyżej.) ... Wyjście skryptu, pokazane poniżej, pochodzi z 4 plików wejściowych o nazwie F1 F2 F3 F4 ...
Oto moja oryginalna odpowiedź (nieco przycięta zamiast powyższego skryptu)
Używając,
wc
aby uzyskać szerokość kolumny ised
prawy pad z widocznym znakiem.
(tylko dla tego przykładu) ... a następniepaste
połączyć dwie kolumny znakiem tab ...Jeśli chcesz uzupełnić prawą kolumnę:
źródło
Jesteś prawie na miejscu.
paste
umieszcza znak tabulacji między każdą kolumną, więc wszystko, co musisz zrobić, to rozwinąć tabulatory. (Zakładam, że twoje pliki nie zawierają tabulatorów.) Musisz określić szerokość lewej kolumny. Przy (wystarczająco niedawnych) narzędziach GNUwc -L
pokazuje długość najdłuższej linii. W innych systemach wykonaj pierwsze przejście z awk. Jest+1
to ilość pustego miejsca między kolumnami.Jeśli masz narzędzie kolumny BSD, możesz go użyć do określenia szerokości kolumny i rozwinięcia zakładek za jednym razem. (
␉
to dosłowny znak tabulacji; pod bash / ksh / zsh możesz użyć$'\t'
zamiast tego, i w dowolnej powłoce, której możesz użyć"$(printf '\t')"
).źródło
wc
polecenie musi być:wc -L <left.txt
... ponieważ gdy nazwa pliku jest spedyfikowana jako arg wiersza polecenia , jego nazwa jest wyprowadzana na standardowe wyjścieJest to wieloetapowe, więc nie jest optymalne, ale proszę bardzo.
1) Znajdź długość najdłuższej linii
file1.txt
.W twoim przykładzie najdłuższa linia to 22.
2) Użyj awk, aby wstawić
file1.txt
, wypełniając każdą linię mniej niż 22 znaki do 22 za pomocąprintf
instrukcji.Uwaga: W przypadku FS użyj ciągu, który nie istnieje w
file1.txt
.3) Użyj wklejania tak jak wcześniej.
Jeśli robisz to często, możesz to łatwo zmienić w skrypt.
źródło
while IFS= read -r line
, w przeciwnym razie powłoka będzie mieszać białe spacje i odwrotne ukośniki. Ale powłoka nie jest najlepszym narzędziem do tego zadania; Nowsze wersje mają coreutils GNUwc -L
(patrz odpowiedź Freda), lub użyć awk:awk 'n<length {n=length} END {print +n}'
.Nie jestem w stanie skomentować odpowiedzi Glenna Jackmana, więc dodaję to, aby rozwiązać problem pustych komórek, który zauważył Peter.O. Dodanie znaku zerowego przed każdą kartą eliminuje przebiegi ograniczników, które są traktowane jako pojedyncza przerwa i rozwiązuje problem. (Pierwotnie użyłem spacji, ale użycie znaku null eliminuje dodatkowe spacje między kolumnami.)
Jeśli znak zerowy powoduje problemy z różnych powodów, spróbuj:
lub
Zarówno
sed
icolumn
wydaje się zmieniać w realizacji całej smaków i wersje Unix / Linux, BSD zwłaszcza (i Mac OS X) vs. GNU / Linux.źródło
od -c
i nie widzę żadnych pustych bajtów. Dotyczy to centos i ubuntu.\0
nie działało jakonull
sed, ale działało\x0
. Jednak wtedy kolumna podałaline too long
błąd. Najprostszą rzeczą wydaje się być użycie przestrzeni i życie z dodatkową postacią.Opierając się na odpowiedzi bahamata : można tego dokonać całkowicie
awk
, czytając pliki tylko raz i nie tworząc żadnych plików tymczasowych. Aby rozwiązać problem zgodnie z opisem, wykonajPodobnie jak w przypadku wielu
awk
skryptów tego rodzaju, powyższe pierwsze czytafile1
, zapisując wszystkie dane wsave
tablicy i jednocześnie obliczając maksymalną długość linii. Następnie odczytujefile2
i drukuje zapisane (file1
) dane obok siebie z bieżącymifile2
danymi ( ). Wreszcie, jeślifile1
jest dłuższy niżfile2
(ma więcej wierszy), wypisujemy kilka ostatnich wierszyfile1
(tych, dla których nie ma odpowiadającej linii w drugiej kolumnie).Jeśli chodzi o
printf
format:"%-nns"
wypisuje ciąg wyrównany do lewej strony w polu onn
szerokości znaków."%-*s", nn
robi to samo -*
każe pobrać szerokość pola z następnego parametru.maxlength+2
nn
+2
Powyższy skrypt działa tylko dla dwóch plików. Można go w prosty sposób zmodyfikować, aby obsługiwał trzy pliki lub cztery pliki itp., Ale byłoby to żmudne i pozostawione jako ćwiczenie. Jednak, jak się okazuje, nie będzie trudno go zmodyfikować, aby obsługiwać dowolną liczbę z plików:
Jest to bardzo podobne do mojego pierwszego skryptu, z wyjątkiem tego, że
max_length
się w tablicę.max_FNR
się w tablicę.save
się w dwuwymiarowy układ.END
bloku.źródło
paste
to najlepsze rozwiązanie; konkretnie, glenn jackman'spaste file1 file2 | column -s $'\t' -t
. Ale pomyślałem, że fajnie byłoby spróbować poprawićawk
podejście.