Usunąć określone numery linii z pliku tekstowego za pomocą sed?
Chcę usunąć jeden lub więcej konkretnych numerów linii z pliku. Jak miałbym to zrobić używając sed?
6 answers
Jeśli chcesz usunąć linie od 5 do 10 i 12:
sed -e '5,10d;12d' file
Spowoduje wydrukowanie wyników na ekranie. Jeśli chcesz zapisać wyniki do tego samego pliku:
sed -i.bak -e '5,10d;12d' file
Spowoduje powrót pliku do file.bak
i usunięcie podanych linii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 20:12:07
I awk również
awk 'NR!~/^(5|10|25)$/' file
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-22 00:57:09
Możesz usunąć konkretny pojedynczy wiersz z jego numerem linii przez sed-i ' 33D ' plik
Spowoduje to usunięcie linii na 33 numerze linii i zapisanie zaktualizowanego pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 05:40:49
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-21 20:12:09
Jest to bardzo często objaw antypaternu. Narzędzie, które wytworzyło numery linii, można zastąpić narzędziem, które natychmiast usuwa linie. Na przykład;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(gdzie deletelines
jest narzędziem, które sobie wyobrażasz, czego potrzebujesz) jest taki sam jak
grep -v error logfile
Powiedziawszy to, jeśli jesteś w sytuacji, w której naprawdę musisz wykonać to zadanie, możesz wygenerować prosty skrypt sed
z pliku numerów linii. Humorystycznie (ale może nieco myląco) ty można to zrobić za pomocą sed
.
sed 's%$%d%' linenumbers
To przyjmuje Plik z numerami linii, po jednym na linię, I tworzy, na standardowym wyjściu, te same numery linii z d
dołączane po każdym z nich. Jest to poprawny skrypt sed
, który możemy zapisać do pliku lub (na niektórych platformach) przenieść do innej instancji sed
:
sed 's%$%d%' linenumbers | sed -f - logfile
Na niektórych platformach sed -f
nie rozumie argumentu opcji -
oznaczającego standardowe wejście, więc musisz przekierować skrypt do pliku tymczasowego i wyczyścić go, gdy gotowe, a może zastąp lone dash /dev/stdin
lub /proc/$pid/fd/1
Jeśli Twój system operacyjny (lub powłoka) tak ma.
Jak zawsze, możesz dodać -i
przed opcją -f
, Aby sed
edytował plik docelowy w miejscu, zamiast generować wynik na standardowym wyjściu. Na platformach * BSDish (w tym OSX) musisz również podać jawny argument -i
; powszechnym idiomem jest podanie pustego argumentu; -i ''
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 05:45:28
Chciałbym zaproponować uogólnienie za pomocą awk.
Gdy plik jest tworzony przez bloki o ustalonym rozmiarze a linie do usunięcia są powtarzane dla każdego bloku, awk może działać dobrze w taki sposób
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
W tym przykładzie rozmiar bloku wynosi 2000 i chcę wydrukować linie [1..713] i [1026..1029].
-
NR
jest zmienną używaną przez awk do przechowywania bieżącego numeru linii. -
%
daje pozostałość (lub moduł) podziału dwóch liczby całkowite; -
nl=((NR-1)%BLOCKSIZE)+1
tutaj zapisujemy zmienną nl numer linii wewnątrz bieżącego bloku. (patrz niżej) -
||
i&&
są operatorem logicznym lub oraz oraz. -
print $0
pisze pełną linię
Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 14:07:54