Jak podzielić duży plik na dwie części, według wzoru?
Podany przykład file.txt
:
ABC
EFG
XYZ
HIJ
KNL
Chcę podzielić ten plik XYZ
tak, aby file1
zawierał wiersze w górę XYZ
i resztę wierszy file2
.
text-processing
sed
awk
split
d.putto
źródło
źródło
XYZ
wiersz powinien być zawarty w wyniku, czy nie?Odpowiedzi:
Dzięki
awk
niemu możesz:Objaśnienie: Pierwszy
awk
argument (out=file1
) definiuje zmienną z nazwą pliku, która będzie używana do wyjścia, podczaslargefile
przetwarzania kolejnego argumentu ( ).awk
Program drukuje wszystkie linie do pliku określonego przez zmiennąout
({print >out}
). Jeśli wzorzecXYZ
zostanie znaleziony, zmienna wyjściowa zostanie ponownie zdefiniowana w celu wskazania nowego pliku ({out="file2}"
), który zostanie użyty jako cel do wydrukowania kolejnych linii danych.Bibliografia:
źródło
To jest praca dla
csplit
:byłoby
s
ilently podzielić plik, tworząc kawałki z pref
IXfile
in
umbered użyciu pojedynczej cyfry, npfile0
itd. Zauważ, że używanie/regex/
byłoby rozdzielić, ale nie w tym wierszu, który pasujeregex
. Aby podzielić i uwzględnić dopasowanie linii,regex
dodaj+1
przesunięcie:Spowoduje to utworzenie dwóch plików
file0
ifile1
. Jeśli absolutnie potrzebujesz ich nazwyfile1
ifile2
zawsze możesz dodać pusty wzór docsplit
polecenia i usunąć pierwszy plik:tworzy
file0
,file1
afile2
alefile0
jest pusty, dzięki czemu można bezpiecznie go usunąć:źródło
Z nowoczesnym
ksh
oto wariant powłoki (tj. Bezsed
) jednej zsed
powyższych odpowiedzi na podstawie:I inny wariant
ksh
sam (tj. Również z pominięciemcat
):(Czyste
ksh
rozwiązanie wydaje się być dość wydajne; w pliku testowym 2,4 GB potrzebowało 19-21 sekund, w porównaniu do 39-47 sekund z podejściem opartym nased
/cat
).źródło
read
iprint
powinieneś po prostu pozwolić mu odejść i wydać własne. Wydajność staje się lepsza, jeśli zbudujesz kompletny zestaw narzędzi AST iksh
skompilujesz wszystkie wbudowane komponenty - to dziwne dla mnie, żesed
tak naprawdę nie jest jednym z nich. Ale przy takich rzeczach, jakwhile <file do
sądzę, nie potrzebujeszsed
tak dużo ...awk
wypadła twoja analiza? I chociaż jestem prawie pewien,ksh
że prawdopodobnie zawsze wygra tę walkę, jeśli używasz GNUsed
, nie jesteś wobec tego zbyt uczciwysed
- GNU jest-u
nieprzyzwoite podejście do POSIXLY zapewniania przesunięcia deskryptora w miejscu wyjścia programu to - nie powinno być potrzeby spowalniania normalnej pracy programu - buforowanie jest w porządku - wszystko, cosed
musisz zrobić, to poszukać deskryptora po zakończeniu. Z jakiegokolwiek powodu GNU odwraca tę mentalność.while
; drukowanie jest domyślnie wykonywane jako zdefiniowany efekt uboczny<##
operatora przekierowania. I tylko pasująca linia wymaga wydrukowania. (W ten sposób implementacja funkcji powłoki jest najbardziej elastyczna dla obsługi włączania / wyłączania.) Wyraźnawhile
pętla oczekiwałbym, że będzie znacznie wolniejsza (ale nie sprawdzona).head
zamiastread
; wydaje się tylko trochę wolniej, ale to jest kod terser:{ head -1 <##XYZ ; { read <##"" ;} >file4 ;} <largefile >file3
.W GNU
sed
powinieneś użyć-u
przełącznika nbuffered. Większość innychsed
powinna po prostu działać.Aby pominąć XYZ ...
źródło
Wypróbuj to z GNU sed:
źródło
sed -e '1,/XYZ/{w file1' -e 'd}' large_file > file2
Łatwym hackiem jest wydrukowanie do STDOUT lub STDERR, w zależności od tego, czy wzorzec docelowy został dopasowany. Następnie można użyć operatorów przekierowania powłoki, aby odpowiednio przekierować dane wyjściowe. Na przykład w Perlu, zakładając, że plik wejściowy jest wywoływany,
f
a dwa pliki wyjściowef1
if2
:Odrzucanie linii pasującej do wzorca podziału:
W tym dopasowana linia:
Alternatywnie, drukuj do różnych uchwytów plików:
Odrzucanie linii pasującej do wzorca podziału:
W tym dopasowana linia:
źródło