Sed dosyasını belirli bir dize içeren bir metin dosyasındaki tüm satırları silmek için nasıl kullanabilirim?
Sed dosyasını belirli bir dize içeren bir metin dosyasındaki tüm satırları silmek için nasıl kullanabilirim?
Yanıtlar:
Çizgiyi kaldırmak ve çıktıyı standart çıkışa yazdırmak için:
sed '/pattern to match/d' ./infile
Dosyayı doğrudan değiştirmek için - BSD sed ile çalışmaz:
sed -i '/pattern to match/d' ./infile
Aynı, ancak BSD sed (Mac OS X ve FreeBSD) için - GNU sed ile çalışmaz:
sed -i '' '/pattern to match/d' ./infile
Doğrudan dosyayı değiştirmek (ve bir yedek oluşturmak) - BSD ve GNU sed ile çalışır:
sed -i.bak '/pattern to match/d' ./infile
sed '/pattern to match/d' ./infile > ./newfileveya yerinde bir düzenleme yapmak istiyorsanız, -ised gibi bayrağı ekleyebilirsiniz sed -i '/pattern to match/d' ./infile. Not -ibayrağı GNU sed gerektirir ve taşınabilir değildir
sed -i.backup '/pattern to match/d' ./infile) Bu beni yerinde düzenlemelerle karşılaştıracak.
sedsürüm kontrollü olmayan dosyalara benzer komutlar uygulamayın .
sed -i '' '/pattern/d' ./infile.
Ayrıca, belirli bir dizeye sahip satırları silmenin birçok yolu vardır sed:
awk '!/pattern/' file > temp && mv temp file
ruby -i.bak -ne 'print if not /test/' file
perl -ni.bak -e "print unless /pattern/" file
while read -r line
do
[[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file
grep -v "pattern" file > temp && mv temp file
Ve elbette sed(tersi yazdırma gerçek silme işleminden daha hızlıdır):
sed -n '/pattern/!p' file
sedörnek farklı bir davranışa sahip, sadece greps! böyle bir şey olmalı sed -n -i '/pattern/!p' file.
grep -v "pattern" file > temp; mv temp fileBu, dönüş değerine bağlı olarak diğer bazı örnekler için geçerli olabilir.
seq -f %f 10000000 >foo.txt. sed d: time sed -i '' '/6543210/d' foo.txtgerçek 0m9.294s. sed! p: time sed -i '' -n '/6543210/!p' foo.txtgerçek 0m13.671s. (Daha küçük dosyalar için fark daha büyüktür.)
Bir dosyada yer alan satırları değiştirmek için sed komutunu kullanabilirsiniz. Bununla birlikte, tersine grep'i ikinci bir dosyaya kullanmaktan ve daha sonra ikinci dosyayı orijinalin üzerine taşımaktan çok daha yavaş görünüyor.
Örneğin
sed -i '/pattern/d' filename
veya
grep -v "pattern" filename > filename2; mv filename2 filename
İlk komut yine de makinemde 3 kat daha uzun sürüyor.
sed '/pattern/d' filename > filename2; mv filename2 filename
GNU ile bunu yapmanın kolay yolu sed:
sed --in-place '/some string here/d' yourfile
-rseçeneği deneyin (veya -Esürümünüze bağlı olarak). Bu regex metakarakterlerin kullanımını sağlayan +, ?, {...}ve (...).
Kullanmayı düşünebilirsiniz ex(standart Unix komut tabanlı bir düzenleyicidir):
ex +g/match/d -cwq file
nerede:
+Ex komutunu ( man ex) -cçalıştırır wq( çalıştır ve çık)g/match/d- Ex komutu verilen satırları silmek için matchbkz .Yukarıdaki örnek, Unix.SE ve POSIX spesifikasyonlarındaex bu gönderiye göre bir dosyayı yerinde düzenlemek için POSIX uyumlu bir yöntemdir .
Aradaki fark sedşudur:
sedBir olan S Team, ED in- değil, bir dosya editörü. BashFAQ
Kaydedilemeyen kod, G / Ç ek yükü ve diğer bazı kötü yan etkilerin tadını çıkarmazsanız. Temel olarak bazı parametreler (yerinde / gibi -i) standart olmayan FreeBSD uzantılarıdır ve diğer işletim sistemlerinde mevcut olmayabilir.
man exo bana adam verir vim, öyle görünüyor exvim bir parçasıdır ... ben doğru anlama geldiğini desen sözdizimi anlamış matcholduğunu vimregex.com POSIX ve PCRE tatlar benzer ancak farklı olan?
Mac'te bununla mücadele ediyordum. Ayrıca, değişken değiştirme kullanarak yapmam gerekiyordu.
Ben de kullandım:
sed -i '' "/$pattern/d" $file
burada $filesilme işleminin gerekli olduğu dosya ve silme işlemi $patterniçin eşleştirilecek modeldir.
Ben ''bu yorumdan aldı .
Burada dikkat edilmesi gereken şey kullanılmasıdır çift tırnak içinde "/$pattern/d". Tek tırnak kullandığımızda değişken çalışmaz.
sedsonra bir parametre gerektirir -i, bu yüzden bir yedekleme istemiyorsanız, yine de boş bir dize eklemeniz gerekir:-i ''
sed -i "/$pattern/d" $file. Cevabınız için teşekkür ederim.
Yaklaşık 345 000 satır içeren bir dosya ile küçük bir karşılaştırma yaptım. İle yolu grepyaklaşık 15 kat daha hızlı daha gibi görünüyor sedbu durumda yöntemin.
Hem ve ayar LC_ALL = C olmadan denedim, önemli ölçüde zamanlamaları değiştirmek görünmüyor. Arama dizesi (CDGA_00004.pdbqt.gz.tar), dosyanın ortasında bir yerdedir.
İşte komutlar ve zamanlamalar:
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
Bunu da kullanabilirsiniz:
grep -v 'pattern' filename
Burada -vsadece deseninizden başka bir şey yazdıracak (tersine eşleşme anlamına gelir).
perl -i -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3
İlk komut dosya (ları) yerinde (-i) düzenler.
İkinci komut aynı şeyi yapar, ancak dosya adlarına .bk ekleyerek orijinal dosyaların bir kopyasını veya yedeklemesini saklar (.bk herhangi bir şeyle değiştirilebilir).
Birisinin dizelerin tam eşleşmeleri için bunu yapmak istemesi durumunda, -wbayrağı bütün olarak grep - w'de kullanabilirsiniz . Örneğin, 11 numaralı satırları silmek, ancak 111 numaralı satırları tutmak istiyorsanız:
-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
Aynı -fanda birkaç kesin deseni hariç tutmak istiyorsanız bayrakla da çalışır . "Kara liste", her satırda "dosya" dan silmek istediğiniz çeşitli desenlere sahip bir dosyaysa:
grep -w -v -f blacklist file
-w, --word-regexp Select only those lines containing matches that form whole words.vs-x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
işlenen metni konsolda göstermek için
cat filename | sed '/text to remove/d'
işlenen metni bir dosyaya kaydetmek için
cat filename | sed '/text to remove/d' > newfile
işlenen metin bilgilerini mevcut bir dosyaya eklemek için
cat filename | sed '/text to remove/d' >> newfile
önceden işlenmiş metni işlemek için, bu durumda, kaldırılanların daha fazla satırını kaldırın
cat filename | sed '/text to remove/d' | sed '/remove this too/d' | more
| moreher seferinde bir sayfanın parçalar metni gösterecektir.
Eski iyi kullanabilirsiniz edbenzer bir şekilde düzenlemek için bir dosya cevap kullanımları olduğunu ex. Bu durumda en büyük fark ed, komutlarını exkutu gibi komut satırı argümanları olarak değil, standart girdi yoluyla almasıdır . Bir komut dosyasında kullanırken, bunu kabul etmenin genel yolu printfkomutları borulamak için kullanmaktır :
printf "%s\n" "g/pattern/d" w | ed -s filename
veya bir yorumlu metinle:
ed -s filename <<EOF
g/pattern/d
w
EOF