Odpowiedzi:
Z sed
:
sed '20,37d; 45d' < input.txt > output.txt
Jeśli chcesz to zrobić w miejscu:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed ”robi to, tworząc plik tymczasowy i wysyłanie danych wyjściowych do tego pliku zamiast na standardowe dane wyjściowe. ... Nie znam żadnego innego „sed”, ale logistyka aktualizacji „w miejscu” za pomocą edytora strumieniowego nie „oblicza” :)
Jeśli plik wygodnie mieści się w pamięci, możesz również użyć ed
.
Polecenia są dość podobne do sed
powyższego z jedną zauważalną różnicą : musisz przekazać listę numerów / zakresów linii, które mają zostać usunięte, w porządku malejącym (od najwyższego numeru linii / zakresu do najniższego). Powodem jest to, że kiedy usuwasz / wstawiasz / dzielisz / łączysz linie ed
, bufor tekstowy jest aktualizowany po każdej podkomendie, więc jeśli usuniesz niektóre linie, reszta kolejnych linii nie będzie już w tej samej pozycji w buforze, gdy następna komenda jest wykonywana. Musisz zacząć od tyłu 1 . Edycja w
miejscu :
ed -s in_file <<IN
45d
20,37d
w
q
IN
lub
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
lub
printf '%s\n' 45d 20,37d w q | ed -s in_file
Zamień w
obrzęd na ,p
rint, jeśli chcesz wydrukować wynikowe wyjście zamiast pisać do pliku. Jeśli chcesz zachować oryginalny plik nienaruszony i zapisać w innym pliku, możesz przekazać nową nazwę pliku do w
komendy obrzędowej:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
Chyba że chcesz obliczyć nowe numery wierszy po każdym d
elete, co w tym konkretnym przypadku jest dość trywialne (po usunięciu wierszy 20-37, tj. 18 wierszy, wiersz 45 staje się wierszem 27), abyś mógł uruchomić:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Jeśli jednak musisz usunąć wiele numerów / zakresów linii, praca wstecz nie jest żadnym problemem.
q
polecenie jest przydatne na końcu? Wydaje mi się, że tak czy inaczej.
Po prostu wczytaj go do pamięci, zmień, a następnie zapisz. Możesz zrobić coś takiego
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
Testowany z 5-wierszowym plikiem. Podziękowania dla http://pleac.sourceforge.net/pleac_python/fileaccess.html , patrz sekcja „Modyfikowanie pliku na miejscu bez pliku tymczasowego”. Zobacz także /programming/125703/how-do-i-modify-a-text-file-in-python
Niektóre uwagi:
Można najpierw obciąć plik, a następnie napisać do niego, zamiast pisać, a następnie obciąć, jak wyżej. Jednak nie znam flagi Pythona, która pozwala czytać, a następnie robić okrojone zapisy. Ale może coś mi brakuje, ponieważ dokument nie jest tak jasny. Co prowadzi mnie do
Czasami dokumenty Pythona są naprawdę do kitu. Zobacz http://docs.python.org/library/functions.html#open
Tryby „r +”, „w +” i „a +” otwierają plik do aktualizacji (zwróć uwagę, że „w +” obcina plik).
Czy to coś dla ciebie znaczy? Co do cholery jest „otwarte na aktualizację”?
Nie wiem, czy robienie tego w Pythonie w przeciwieństwie do czegoś uniksowego, takiego jak edytor strumieni, jest lepsze. Może być bardziej przenośny, ale nie wiem, jak przenośny jest sed. Właśnie to napisałem, ponieważ czuję się bardziej komfortowo z programowaniem na niskim poziomie niż przy użyciu klasycznych narzędzi unixowych, które są dobre, jeśli robią dokładnie to, co chcesz, ale (myślę) są ogólnie mniej elastyczne.
To podejście (manipulowanie plikiem w pamięci) wymienia pamięć na miejsce na dysku. Powinien działać dobrze na komputerach z kilkoma GB pamięci dla plików do kilkuset Mb. Python nie radzi sobie bardzo dobrze z łańcuchami, więc na przykład przejście na C / C ++ nieznacznie zwiększy wydajność i znacznie zmniejszy użycie pamięci.
Możesz używać Vima w trybie Ex:
ex -sc '20,37d|45d|x' file
d
kasować
x
Zapisz i zamknij