Mam plik tekstowy podobny do tego:
line 1
line 2A
line 3
line 4A
line 5
Chcę „grep” z „linii 2A” do końca pliku, coś takiego
cat file.txt|some_grep "line 2A"
Chcę też „grep” z „linii 2A” do następnej linii zawierającej „A”, coś w tym rodzaju
cat file.txt| some_grep "A"
Chcę to wydrukować:
line 2A
line 3
line 4A
Które polecenie może mi w tym pomóc?
linux
command-line
phong
źródło
źródło
awk '/line 2A/,0'
a drugim może byćawk '/line 2A/,/A/&&!/line 2A/'
lub jeśli jest to co najmniej jeden znak przed Aawk '/line 2A/,/[^2]A/'
Odpowiedzi:
(rozwinięty z komentarza)
awk
ma możliwość wybrania „zakresów” linii, które idealnie pasują do tej potrzeby, jak opisano w instrukcji GNU-awk (gawk) . (Ta funkcja działa w innychawk
systemach, alegawk
instrukcja jest łatwa do połączenia).awk '/line 2A/,0'
wypisuje linie zaczynające się od pierwszego pasującegoline 2A
i kontynuujące do końca wprowadzania, ponieważ0
jest to warunek, który nigdy nie jest prawdziwy.awk '/line 2A/,/A/&&!/line 2A/'
rozpoczyna drukowanie od linii pasującejline 2A
i zatrzymuje się po linii pasującej,A
ale NIEline 2A
(a zatem nie może być tej samej linii co linia początkowa). Zacznie się od następnegoline 2A
i tak dalej; jeśli chcesz temu zapobiec, istnieją nieco bardziej skomplikowane sposoby.Jeśli linie zatrzymujące zawsze mają jakiś znak inny niż
2
przedtem,A
można to uprościć, doawk '/line 2A/,/[^2]A/'
którego kończy się po linii pasującej do dowolnego znaku innego niż 2, a następnie A. Możesz chcieć odmiany tego, np. Aby zatrzymać na dowolnym pojedynczym- cyfra-A różna od 2A, ale nie inna jak podobnaWHAT
; do tego może być warunkiem zatrzymania,/line [013-9]A/
.źródło
sed
domyślne wyjścieźródło
some_grep "A"
która sugeruje, że OP chce najmniejszego zakresu linii między dwiema zawierającymi „A”. Zdefiniowanie zakresu od / 2A / do / A / jest szczególnym przypadkiem i obejściem, a nie odpowiedzią.sed -n '/A/,/A/p'
jest zła odpowiedź. Wypróbuj z plikiem wejściowym zawierającym więcej niż dwa wiersze zawierające „A”.Myślę, że najlepszym sposobem jest użycie
grep
w połączeniu zcut
itail
. Najpierw użyj grep, aby uzyskać linię, w której znajduje się żądany ciąg (-n
do wypisania numeru linii;-m 1
aby zatrzymać wyszukiwanie po pierwszym dopasowaniu):grep -n -m 1 "somestring" filename.txt
To wyświetla numer linii i sam łańcuch. Aby odciąć ciąg, używamy cut (
-f1
: wyjściowe pierwsze pole;-d:
użyj „:” jako separatora):grep -n -m 1 "somestring" filename.txt | cut -f1 -d:
Następnie używamy wyniku tego polecenia jako parametru w tail. Zwykle ogon drukuje ostatnie k linii, ale używając
-n +k
, otrzymujemy ogon do drukowania od linii k wzwyż. Łączne polecenie to:Aby wypisać linie do
somestring
użyciahead
zamiasttail
i-n -#
zamiast-n +#
. Możesz także połączyć oba, aby uzyskać linie od jednego ciągu do drugiego.źródło
Wypróbuj poniższy kod -
źródło
Metoda sed jest właściwą drogą, ale co zrobić, jeśli chcesz zachować górne linie, ale ich nie grepować?
Oto sposób:
Co tu się dzieje?
Najpierw wypluwamy górną linię (head -1 plik.txt) Następnie usuwamy górną linię (sed 1d plik.txt) i grep właśnie to.
Całość jest otoczona przez {..;}, więc możesz później potokować lub przekierowywać zarówno nagłówek, jak i grepowane ciało. Lubię to:
{head -1 plik.txt; sed 1d plik.txt | grep;}> newfile.txt
Jeśli chcesz pominąć pierwsze 10 linii, zmień to na to
{head -10 plik.txt; sed 1,10d plik.txt | grep;}
źródło