mój plik tekstowy wygląda następująco:
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
teraz chcę usunąć Liquid penetration 95% mass (m)
z moich linii, aby uzyskać tylko wartości. Jak mam to zrobić?
grep -o '[^[:space:]]\+$' file
\S+$
albo-E
albo-P
.) Tak więc tego rodzaju rozwiązanie nie jest z natury powolne. Ale nadal nie mogę go zbliżyć do metody αғsнιηcut
, która również wygrała Twój test porównawczy .Odpowiedzi:
Jeśli jest tylko jeden
=
znak, możesz usunąć wszystko wcześniej i w=
ten sposób:Jeśli chcesz zmienić oryginalny plik, użyj
-i
opcji po przetestowaniu:Notatki
-r
użyj ERE, abyśmy nie musieli uciekać(
i)
s/old/new
wymienićold
znew
.*
dowolna liczba dowolnych znaków(things)
zapiszthings
się wsteczne później\1
,\2
itpźródło
s/^.*= //
działałoby równie dobrze, ponieważ poprawna wartość znajduje się na końcu wiersza.\1
etc ma wartość dla ludzi, którzy wyląduj na tym pytaniu podczas wyszukiwania, którzy nie mają tak prostego problemuTo jest praca dla
awk
; zakładając, że wartości występują tylko w ostatnim polu (jak w twoim przykładzie):NF
jestawk
zmienną, rozwija się do liczby pól w rekordzie (linii), dlatego$NF
(zwróć uwagę na$
początek) zawiera wartość ostatniego pola.Przykład:
źródło
Postanowiłem porównać różne rozwiązania wymienione tutaj. W tym celu stworzyłem duży plik, oparty na treści dostarczonej przez PO:
Utworzyłem prosty plik o nazwie
input.file
:Następnie wykonałem tę pętlę:
Okno terminala zostało zablokowane. Wykonałem
killall tee
z innego terminala. Następnie sprawdziłem zawartość pliku za pomocą poleceń:less input.file
icat input.file
. Wyglądało dobrze, z wyjątkiem ostatniej linii. Więc usunąłem ostatni wiersz i utworzyłem kopię zapasową:cp input.file{,.copy}
(z powodu poleceń, które używają opcji inplace ).Ostateczna liczba wierszy w pliku
input.file
wynosi 2 192 473 . Mam ten numer przez poleceniewc
:Oto wynik porównania:
grep -o '[^[:space:]]\+$'
sed -ri 's/.* = (.*)/\1/'
Alternatywnie, jeśli przekierujemy dane wyjściowe do nowego pliku, polecenie jest szybsze:
gawk '{gsub(".*= ", "");print}'
rev | cut -d' ' -f1 | rev
grep -oP '.*= \K.*'
sed 's/.*= //'
(odpowiednio-i
opcja powoduje, że polecenie jest kilka razy wolniejsze)perl -pe 's/.*= //'
(-i
opcja nie powoduje tutaj dużej różnicy w wydajności)awk '{print $NF}'
cut -c 35-
cut -d= -f2
Źródło pomysłu.
źródło
cut -d= -f2
rozwiązanie wygrywa. hahawc -l
wypisuje trzy liczby? Gdy nie zostaną przekazane żadne inne opcje,-l
opcja powinna pomijać wszystko oprócz liczby linii.wc
rzeczywiście wyświetlał te spacje? Czy istnieją ustawienia regionalne, dla których to zrobi?) Dziękujemy za aktualizację!wc
jeszcze raz. Nie wiem, gdzie dzisiaj był mój rozum, ale naprawdę nie mogłem ich zrozumieć. Rzeczywiście spacje były cyfrowymi separatorami grup iwc
nie dodają ich :)O
grep
a-P
o oPCRE
(interpretować szablon jako P erl- C ompatible R egular E Xpression) i-o
drukowanie dopasowane samego wzoru.\K
Zawiadomić zignoruje dopasowana część przyjść przed siebie.Lub
cut
zamiast tego możesz użyć polecenia.źródło
cut
Ponieważ prefiks linii ma zawsze tę samą długość (34 znaki), możesz użyć
cut
:źródło
Odwróć zawartość pliku za pomocą
rev
, potokuj wyjście zacut
pomocą spacji jako separatora i 1 jako pola docelowego, a następnie odwróć go ponownie, aby uzyskać oryginalny numer:źródło
To jest proste, krótkie i łatwe do napisania, zrozumienia i sprawdzenia, a ja osobiście to lubię:
grep
w Ubuntu , gdy jest wywoływany za pomocą-E
lub-P
, oznacza skrót,\s
że oznacza spację (w praktyce zwykle spację lub tabulator) i\S
oznacza wszystko, co nie jest jednym. Używając kwantyfikatora+
i kotwicy końca linii$
, wzór\S+$
dopasowuje jeden lub więcej niepustych znaków na końcu linii . Możesz użyć-P
zamiast-E
; znaczenie w tym przypadku jest takie samo, ale używany jest inny silnik wyrażeń regularnych , więc mogą mieć różne charakterystyki wydajności .Jest to równoważne z komentarzem rozwiązania Avinash Raj (tylko z łatwiejszą, bardziej zwartą składnią):
Te podejścia nie będą działać, jeśli po numerze mogą występować białe spacje . Można je modyfikować, ale robią to, ale nie widzę sensu w tym wchodzić. Chociaż czasem pouczające jest uogólnienie rozwiązania do pracy w większej liczbie przypadków, nie jest to praktyczne tak często, jak ludzie się przypuszczają, ponieważ zwykle nie ma sposobu, aby dowiedzieć się, na który z wielu różnych niekompatybilnych sposobów problem może ostatecznie wymagać uogólniać się.
Wydajność jest czasem ważnym czynnikiem. To pytanie nie określa, że dane wejściowe są bardzo duże i prawdopodobne jest, że każda opublikowana tutaj metoda jest wystarczająco szybka. Jednak w przypadku, gdy pożądana jest prędkość, oto mały punkt odniesienia dla pliku wejściowego o wartości dziesięciu milionów wierszy:
Uruchomiłem go dwa razy, na wypadek, gdyby kolejność miała znaczenie (jak to czasem bywa w przypadku zadań wymagających dużej ilości operacji we / wy) i ponieważ nie miałem dostępnej maszyny, która nie wykonywałaby w tle innych rzeczy, które mogłyby wypaczać wyniki. Na podstawie tych wyników wyciągam następujące wnioski, przynajmniej tymczasowo i dla plików wejściowych o rozmiarze, którego użyłem:
Łał! Przechodząc
-P
(by użyć PCRE ) zamiast-G
(domyślnie, gdy nie jest określony dialekt) lub-E
wykonanegrep
szybciej o ponad rząd wielkości. Dlatego w przypadku dużych plików lepiej użyć tego polecenia niż powyższe:ŁAŁ!!
cut
Metoda w odpowiedzi αғsнιη za , jest ponad rząd wielkości szybciej niż nawet szybszą wersją mojej drodze! Był również zwycięzcą testu porównawczego pa4080 , który obejmował więcej metod niż to, ale przy mniejszym wkładzie - i dlatego wybrałem go spośród wszystkich innych metod do włączenia do mojego testu. Jeśli wydajność jest ważna lub pliki są ogromne, uważam, że należy zastosować metodę αғsнιη .cut -d= -f2 file
cut
Służy to również przypomnieniu, że nie należy zapominać o prostocie
cut
ipaste
narzędziach , i być może należy ją preferować, gdy ma to zastosowanie, mimo że istnieją bardziej wyrafinowane narzędzia, takie jak te,grep
które są często oferowane jako rozwiązania pierwszej linii (i że jestem osobiście bardziej przyzwyczajony do korzystania).źródło
perl
- s tworzy wzór/.*= /
z pustym łańcuchem//
:Od
perl --help
:sed
- zamień wzór na pusty ciąg:lub (ale wolniej niż powyżej) :
gawk
- zamień wzór na".*= "
pusty ciąg""
:Od
man gawk
:źródło