Mam pliki, które zostały wygenerowane przez program, który nie umieścił znaku nowej linii na końcu rekordów. Chcę wstawić znaki nowego wiersza między rekordami i mogę to zrobić za pomocą prostego skryptu sed:
sed -e 's/}{/}\n{/g'
Problem polega na tym, że pliki wejściowe mają rozmiar wielu gigabajtów, a zatem linie wejściowe do sed mają wiele GB. sed próbuje utrzymać linię w pamięci, co w tym przypadku nie działa. Wypróbowałem tę --unbuffered
opcję, ale wydawało się, że spowalnia ją i nie pozwala poprawnie zakończyć.
tr
do przetłumaczenia}
na\n
, a następnie użyćsed
, aby dodać}
na końcu każdego wiersza? W ten sposób:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
powtarzane, aż wystarczy kilka gigabajtów.dd if=file cbs=80 conv=unblock
, zrobiłby to - ale rzadko jest to takie proste.Odpowiedzi:
Możesz użyć innego narzędzia, które pozwala ustawić separator rekordów wejściowych. Na przykład
Perl
Zmienna specjalna
$/
to separator rekordów wejściowych. Ustawienie go}{
definiuje linie jako kończące się na}{
. W ten sposób możesz osiągnąć to, co chcesz, bez wczytywania całej pamięci do pamięci.jastrząb lub gawk
To ten sam pomysł.
RS="}{"
ustawia separator rekordów na,}{
a następnie drukuje}
, nowy wiersz{
(z wyjątkiem pierwszego rekordu) i bieżący rekord.źródło
Perl na ratunek:
Ustawienie,
$/
aby\1024
odczytać plik w kawałkach 1024 bajtów. Te$closing
uchwyty zmienne przypadku, gdy skończy się chunk w}
a kolejny rozpoczyna się{
.źródło
Powinieneś zrobić:
To chyba najbardziej wydajne rozwiązanie.
Która stawia
{}
chronić ewentualne dane spływu. Za pomocą jeszcze jednegotr
procesu możesz to zamienić i zrobić pustą linię na początku pierwszego{
pola. Lubić...Tak więc pierwsza z przykładowymi danymi don:
... a drugi robi ...
W drugim przykładzie nie ma końca nowego wiersza - chociaż jest jeden dla pierwszego.
źródło
sed
Narzędzie binarne o nazwiebbe
W tym przypadku uważam, że najłatwiej jest pozostać przy składni podobnej do sed.
I wiele wolą za pomocą
bbe
narzędzia (dostępne za pośrednictwem {Uni, Linu} instalacji pakiet X., eqapt-get
). Lub tutaj, jeśli jesteś jednym z gitów, chociaż ja osobiście nie sprawdziłem tego konkretnego linku.1. Obsługuje
s/before/after/
idiomJest to „Binary Block Editor”, który obsługuje operacje podobne do sed (między innymi). Obejmuje to bardzo popularny
s/before/after/
idiom podstawienia, którego potrzebujesz. Uwaga: ponieważ zbbe
punktu widzenia nie ma linii jako takich, na końcu polecenia nie ma „globalnego g”.Jako szybki test (zwróć uwagę na wymagane
-e
):produkuje:
2. W twoim przypadku konkretnego dnia
}{
do}\n{
konwersjiWięc jeśli mieliśmy ogromny plik wypełniony milionów numerów (powiedzmy) w formacie
{1}{2}{3}
...{1000000}
bez powrotu karetki, możemy wymieniać}{
się}\n{
łatwo i mają wszystkie numery jeden na linię.Byłoby to z tym
bbe
poleceniem:Jak przetestowaliśmy w tej pętli zsh, którą chwytamy za ogon:
Który spowodowałby to:
(oczywiście bez powrotu karetki tylnej).
źródło