Mam plik z liniami jak poniżej.
title1:A1
title2:A2
title3:A3
title4:A4
title5:A5
title1:B1
title2:B2
title3:B3
title4:B4
title5:B5
title1:C1
title2:C2
title3:C3
title4:C4
title5:C5
title1:D1
title2:D2
title3:D3
title4:D4
title5:D5
Jak mogę to osiągnąć?
title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4
text-processing
columns
Dens
źródło
źródło
Odpowiedzi:
Spójrz na GNU datamash, którego można używać jak
datamash transpose
. Przyszła wersja będzie również obsługiwać tabelę krzyżową (tabele przestawne)źródło
Poza toczeniem niestandardowego rozwiązania do transponowania wierszy z kolumnami z wiersza poleceń jedynym narzędziem, jakie kiedykolwiek widziałem, które może to zrobić, jest narzędzie o nazwie ironicznie
transpose
.Instalacja
Niestety nie ma go w repozytorium, więc musisz go pobrać i skompilować. Jest to dość proste, ponieważ nie ma żadnych dodatkowych bibliotek, od których jest zależny. Można to osiągnąć w następujący sposób:
Stosowanie
Z łatwością obsługuje proste pliki tekstowe. Na przykład:
Można transponować za pomocą tego polecenia:
To polecenie służy
transpose
do transpozycji (-t
), a separatorem pól jest spacja (--fsep " "
).Twój przykład
Ponieważ przykładowe dane są w nieco bardziej złożonym formacie, należy się nimi zająć w 2 etapach. Najpierw musimy przetłumaczyć go na format, z którym
transpose
można sobie poradzić.Uruchomienie tego polecenia spowoduje umieszczenie danych w bardziej przyjaznym dla formatu formacie:
Teraz musimy tylko usunąć wtórne wystąpienia tytułu 1, tytułu 2 itd .:
Jest teraz w formacie, z którym
transpose
można sobie poradzić. Następujące polecenie wykona całą transpozycję:źródło
Możesz wtedy użyć
awk
do przetworzenia danychpaste
icolumn
sformatowania ich.Tutaj zakładam, że
title1
jest to tylko przykład w twoim poście i że dane nie zawierają,:
z wyjątkiem separatora między nagłówkiem + danymi.n
oznacza liczbę kolumn do wydrukowania (powinny pasować do myślnikówpaste
).Jeśli chcesz uczynić go bardziej elastycznym i łatwym w utrzymaniu, możesz napisać go jako skrypt. Oto przykład użycia otoki bash
awk
i potoku docolumn
. W ten sposób możesz również sprawdzić więcej danych, np. Upewnić się, że nagłówki są poprawne we wszystkich wierszach itp.Używany zwykle jako:
Jeśli nagłówki zawsze są krótsze niż dane, możesz również zapisać szerokości nagłówków, a następnie za
printf
pomocą%-*s
i pomińcolumn
wszystkie razem.źródło
Oto szybki sposób na umieszczenie pliku w wybranym formacie:
Jeśli chcesz nagłówki kolumn:
Jak działa drugie polecenie
drukowanie banera umieszczenie zwrotu po banerze drukowanie wierszy danychźródło
Narzędzie GNU datamash
Zaczerpnięte z tej strony, https://www.gnu.org/software/datamash/ i http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods
źródło
Prawdopodobnie istnieje bardziej zwięzły sposób sformułowania tego, ale wydaje się, że osiąga to ogólny efekt:
Wiele
sed
wywołań nie jest w porządku (i jestem pewien, że sed również potrafi wykonać tłumaczenie nowej linii), więc prawdopodobnie nie jest to najprostszy sposób na zrobienie tego. Powoduje to również usunięcie potencjalnych nagłówków, ale możesz je wygenerować ręcznie, gdy poprawnie sformatujesz wiersze / pola.Lepsza odpowiedź prawdopodobnie ograniczyłaby ten efekt do samego użycia
sed
lubawk
zrobienia tego, abyś miał tylko jedną rzecz na raz. Ale jestem zmęczony, więc udało mi się to połączyć.źródło
paste
jest prawdopodobnie najlepszym wyborem. Można wyodrębnić odpowiednie bity zcut
,grep
iawk
jak to:Jeśli piąta kolumna powinna zostać wyeliminowana, dodaj w
awk 'NR%5'
ten sposób:Teraz uporządkuj za pomocą
paste
:Wynik:
źródło
Tylko w przypadku części transponowanej miałem ostatnio podobny problem i użyłem:
Dostosuj fmt w razie potrzeby. Dla każdego wiersza wejściowego konkatenuje każde pole z elementem tablicy. Zauważ, że łączenie łańcuchów awk jest niejawne: dzieje się tak, gdy piszesz dwie rzeczy bez żadnego operatora.
Przykładowe I / O:
wynik:
źródło
Najprostszą rzeczą, którą możesz zrobić, to
cut
wyciąć pola, a następnie użyć,tr
jeśli transponujesz wiersze do kolumn, zastępując znak nowej linii znakiem tabulacji: http://www.gnu.org/software/coreutils/manual/ coreutils.html # tr-invocationźródło
cut
zwraca błąd.