Mam następujący plik:
id name age
1 ed 50
2 joe 70
Chcę wydrukować tylko kolumny id
i age
. Teraz używam po prostu awk
:
cat file.tsv | awk '{ print $1, $3 }'
Wymaga to jednak znajomości numerów kolumn. Czy istnieje sposób, aby to zrobić, w którym mogę użyć nazwy kolumny (określonej w pierwszym wierszu) zamiast numeru kolumny?
cat
nie jest konieczne, BTW. Możesz użyćawk '{ print $1, $3 }' file.tsv
id
zamiast$1
iage
zamiast$3
Odpowiedzi:
Może coś takiego:
Jeśli chcesz określić kolumny do wydrukowania w wierszu polecenia, możesz zrobić coś takiego:
(Zwróć uwagę na
-v
przełącznik, aby uzyskać zmienną zdefiniowaną wBEGIN
bloku).źródło
awk -f t.awk col1 col2 ... coln input
byłoby idealne;awk -f t.awk cols=col1,col2,...,coln input
też by działałfor (i in out)
nie ma właściwej kolejności.gawk
oferujePROCINFO["sorted_in"]
jako rozwiązanie, iteracja indeksu za pomocą afor( ; ; )
jest prawdopodobnie lepsza.Wystarczy wrzucić rozwiązanie Perla do partii:
źródło
csvkit
Konwersja danych wejściowych do formatu csv i użyć narzędzia takie jak csv
csvcut
zcsvkit
:Zainstaluj csvkit:
Użyj
tr
z opcją ściśnięcia,-s
aby przekonwertować go na prawidłowy plik csv i zastosowaćcsvcut
:Jeśli chcesz wrócić do starego formatu danych, możesz użyć
tr ',' ' ' | column -t
Notatki
csvkit obsługuje również różne ograniczniki ( opcja współdzielona
-d
lub--delimiter
), ale zwraca plik csv:Jeśli plik używa tylko spacji do oddzielenia kolumn (bez żadnych tabulatorów), następujące czynności
Jeśli plik używa karty do oddzielenia kolumn, następujące prace
csvformat
mogą być użyte do odzyskania pliku tsv:O ile sprawdziłem, dozwolona jest tylko jedna karta.
csvlook
może sformatować tabelę w formacie tabeli przecenionejUUOC (Useless Use Of Cat) : Podoba mi się w ten sposób, aby zbudować polecenie.
źródło
tr
. Pliki TSV są obsługiwane bezpośrednio, bez potrzeby konwertowania ich na CSV. Opcja-t
(aka--tabs
) mówi,cvscut
aby używać tabulatorów jako ograniczników pól. I-d
lub--delimiter
użyć dowolnego znaku jako separatora.-d
i-t
opcje są pół złamane. działają, aby określić separator wejściowy, ale separator wyjściowy jest zakodowany na stałe, aby zawsze był przecinkiem. IMO, który jest zepsuty - powinien być taki sam jak separator wejściowy lub mieć inną opcję umożliwiającą użytkownikowi ustawienie separatora wyjściowego, npawk
. Zmienne FS i OFS.Jeśli chcesz odwoływać się do tych pól według ich nazw zamiast cyfr, możesz użyćread
:EDYTOWAĆ
W końcu zrozumiałem twoje znaczenie! Oto funkcja bash, która wypisze tylko kolumny określone w wierszu poleceń (według nazwy ).
Oto jak możesz go użyć z prezentowanym plikiem:
(Funkcja czyta
stdin
.< file.tsv printColumns ...
Jest równoważna zprintColumns ... < file.tsv
icat file.tsv | printColumns ...
)Uwaga: zwróć uwagę na nazwy żądanych kolumn! Ta wersja nie ma kontroli poprawności, więc mogą się zdarzyć nieprzyjemne rzeczy, jeśli jeden z argumentów jest podobny
"anything; rm /my/precious/file"
źródło
id
,name
aage
nie zmienia faktu, że kolejność jest zakodowane w swojejread
linii.time { command(s); }
).time cat temp.txt | ./col1 CHR POS > /dev/null 99.144u 38.966s 2:19.27 99.1% 0+0k 0+0io 0pf+0w time awk -f col2 c1=CHR c2=POS temp.txt > /dev/null 0.294u 0.127s 0:00.50 82.0% 0+0k 0+0io 0pf+0w
Tyle ile jest warte. Może to obsłużyć dowolną liczbę kolumn w źródle i dowolną liczbę kolumn do wydrukowania, niezależnie od wybranej sekwencji wyjściowej; po prostu przeorganizuj argumenty ...
na przykład. połączenie:
script-name id age
wydajność
źródło
Jeśli plik, który czytasz, nigdy nie mógłby zostać wygenerowany przez użytkownika, możesz nadużyć wbudowanego odczytu:
Cały pierwszy wiersz pliku wejściowego jest podstawiany na listę argumentów, więc
read
wszystkie nazwy pól z wiersza nagłówka są przekazywane jako nazwy zmiennych. Pierwszy z nich otrzymuje 1, któryseq 100
generuje, drugi otrzymuje 2, trzeci otrzymuje 3 i tak dalej. Nadmiarseq
wyjściowy jest pochłaniany przez zmienną fikcyjnąextra
. Jeśli znasz liczbę kolumn wejściowych z wyprzedzeniem, możesz zmienić 100, aby dopasować i się go pozbyćextra
.awk
Skryptu jest dwukrotnie podane łańcuch, co pozwala na zmienne powłoki zdefiniowaneread
mogą być podstawione do scenariusza jakoawk
liczby pól.źródło
Zwykle łatwiej jest spojrzeć na nagłówek pliku, policzyć potrzebną kolumnę ( c ), a następnie użyć Unixa
cut
:Ale kiedy jest wiele kolumn lub plików, używam następującej brzydkiej sztuczki:
Testowany na OSX
file.csv
jest rozdzielany przecinkami.źródło
Oto jeden szybki sposób na wybranie pojedynczej kolumny.
Powiedzmy, że chcemy kolumny o nazwie „foo”:
Zasadniczo weź wiersz nagłówka, podziel go na wiele wierszy z jedną nazwą kolumny na wiersz, ponumeruj linie, wybierz wiersz o żądanej nazwie i odszukaj powiązany numer wiersza; następnie użyj tego numeru wiersza jako numeru kolumny dla polecenia cięcia.
źródło
Szukając podobnego rozwiązania (potrzebuję kolumny o nazwie id, która może mieć różny numer kolumny), natknąłem się na tę:
źródło
Napisałem do tego celu skrypt w języku Python, który działa w następujący sposób:
Nazwałem go
hgrep
do nagłówka grep , może on być stosowany w ten sposób:Cały skrypt jest nieco dłuższy, ponieważ
argparse
analizuje argumenty wiersza poleceń, a kod wygląda następująco:źródło
awk
, jak na cały ten rocznik, jest z natury indeksowany liczbami całkowitymicut
.Oto kilka narzędzi zaprojektowanych do obsługi danych indeksowanych nazwami (większość z nich obsługuje tylko CSV i TSV, które są bardzo popularnymi formatami plików):
źródło
Wypróbuj to małe narzędzie awk, aby wyciąć określone nagłówki - https://github.com/rohitprajapati/toyeca-cutter
Przykładowe użycie -
źródło