Usuwanie linii w pliku tekstowym zawierających określony ciąg znaków
Jak użyć sed, aby usunąć wszystkie linie w pliku tekstowym, które zawierają określony ciąg znaków?
14 answers
Aby usunąć linię I wydrukować wyjście na standardowe wyjście:
sed '/pattern to match/d' ./infile
Aby bezpośrednio zmodyfikować plik:
sed -i '/pattern to match/d' ./infile
Aby bezpośrednio zmodyfikować plik (i utworzyć kopię zapasową):
sed -i.bak '/pattern to match/d' ./infile
Dla użytkowników Mac OS X i FreeBSD:
sed -i '' '/pattern/d' ./infile
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
2018-09-07 12:22:11
Oprócz sed
istnieje wiele innych sposobów usuwania linii z określonym ciągiem znaków:
AWK
awk '!/pattern/' file > temp && mv temp file
Ruby (1.9+)
ruby -i.bak -ne 'print if not /test/' file
Perl
perl -ni.bak -e "print unless /pattern/" file
Shell (bash 3.2 i nowsze)
while read -r line
do
[[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file
GNU grep
grep -v "pattern" file > temp && mv temp file
I oczywiście sed
(drukowanie odwrotności jest szybsze niż rzeczywiste usunięcie):
sed -n '/pattern/!p' 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
2018-09-15 22:06:06
Możesz użyć sed, aby zastąpić wiersze w pliku. Jednak wydaje się, że jest to znacznie wolniejsze niż użycie grepa do odwrotnej zmiany do drugiego pliku, a następnie przeniesienie drugiego pliku nad oryginał.
Np.
sed -i '/pattern/d' filename
Lub
grep -v "pattern" filename > filename2; mv filename2 filename
Pierwsze polecenie i tak trwa 3 razy dłużej na mojej maszynie.
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
2015-08-19 15:07:10
Prosty sposób na to, z GNU sed
:
sed --in-place '/some string here/d' yourfile
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
2017-12-11 23:50:54
Możesz rozważyć użycie ex
(który jest standardowym uniksowym edytorem opartym na poleceniach):
ex +g/match/d -cwq file
Gdzie:
-
+
wykonuje polecenie Ex (man ex
), tak samo jak-c
które wykonujewq
(write and quit) -
g/match/d
- Ex komenda do usuwania linii o podanymmatch
, patrz: moc g
Powyższy przykład jest zgodną z POSIX metodą edycji pliku w miejscu, zgodnie z poniższym postem w Unix.SE i Specyfikacja POSIX na ex
.
Różnica z sed
jest taka, że:
sed
jest S tream ED itor, a nie edytor plików.BashFAQ
Chyba, że lubisz kod nieportable, I / O overhead i inne złe skutki uboczne. Tak więc w zasadzie niektóre parametry (takie jak in-place/-i
) są niestandardowymi rozszerzeniami FreeBSD i mogą nie być dostępne na innych systemach operacyjnych.
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
2018-09-15 22:08:57
Zmagałem się z tym na Macu. Poza tym musiałem to zrobić za pomocą wymiany zmiennych.
Więc użyłem:
sed -i '' "/$pattern/d" $file
Gdzie $file
jest plikiem, w którym potrzebne jest usunięcie, a $pattern
jest wzorcem, który należy dopasować do usunięcia.
Wybrałem ''
z tego komentarza.
Należy tutaj zwrócić uwagę na użycie podwójnych cudzysłowów w "/$pattern/d"
. Zmienna nie będzie działać, gdy użyjemy pojedynczych cudzysłowów.
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
2018-09-15 22:15:45
Aby uzyskać wynik inplace like z grep
możesz to zrobić:
echo "$(grep -v "pattern" filename)" >filename
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
2015-06-13 19:24:59
Zrobiłem mały benchmark z plikiem, który zawiera około 345 000 linii. Sposób z grep
wydaje się być około 15 razy szybszy niż metoda sed
w tym przypadku.
Próbowałem zarówno z ustawieniem LC_ALL=C, jak i bez niego, nie zmienia to znacząco czasu. Szukany ciąg (CDGA_00004.pdbqt.gz.tar) jest gdzieś w środku pliku.
Oto komendy i timingi:
time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt
real 0m0.711s
user 0m0.179s
sys 0m0.530s
time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt
real 0m0.105s
user 0m0.088s
sys 0m0.016s
time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt )
real 0m0.046s
user 0m0.014s
sys 0m0.019s
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
2017-03-19 12:45:18
SED:
AWK:
GREP:
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-09-20 13:28:37
Możesz również użyć tego:
grep -v 'pattern' filename
Tutaj -v
wydrukuje tylko inny wzór niż twój wzór (co oznacza odwrócenie dopasowania).
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
2018-09-15 22:07:13
echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt
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-09-16 23:51:31
perl -i -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3
Pierwsze polecenie edytuje plik(y) w miejscu (-i).
Drugie polecenie robi to samo, ale zachowuje kopię lub kopię zapasową oryginalnych plików przez dodanie .bk do nazw plików (.bk można zmienić na cokolwiek).
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
2018-01-08 12:07:39
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
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
2018-06-29 16:45:24
Na wypadek, gdyby ktoś chciał to zrobić dla dokładnych dopasowań łańcuchów, możesz użyć znacznika -w
w grep-w dla całości. Oznacza to, że na przykład, jeśli chcesz usunąć linie z numerem 11, ale zachować linie z numerem 111:
-bash-4.1$ head file
1
11
111
-bash-4.1$ grep -v "11" file
1
-bash-4.1$ grep -w -v "11" file
1
111
Działa również z flagą -f
, Jeśli chcesz wykluczyć kilka dokładnych wzorców naraz. Jeśli "czarna lista" jest plikiem z kilkoma wzorami w każdej linii, którą chcesz usunąć z"pliku":
grep -w -v -f blacklist 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
2018-09-15 22:18:52