Bir dosyadaki her satırın 5. kelimesini nasıl silebilirim?


13

Bir dosyadaki her satırın 5. kelimesini silmek istiyorum.

Dosyanın geçerli içeriği:

File is not updated or and will be removed  
System will shut down f within 10 seconds  
Please save your work 55 or copy to other location  
Kindly cooperate with us D  

Beklenen çıktı:

File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us

Yanıtlar:


31

Nasıl olur cut:

$ cut -d' ' -f1-4,6- file.txt 
File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us
  • -d' ' ayırıcıyı boşluk olarak ayarlar

  • -f1-4,6- ilk alandan 4. alana (sözcük) seçerek 5. alandan çıkıp 6. sayfadan diğer sayfalara yazdırmaya devam edin.


11

Aşağıdakileri içeren bir çözüm cut:

cut -d ' ' -f1-4 -f6- FILE

Birden fazla -fbenim cut(GNU) desteklenmiyor ..
heemayl

BSD kesiminde destekleniyor ama cevabınızı benimkinden daha çok seviyorum.
fd0

1
GNU kesim ise, o kadar --complementşeyler basitleştirmek için bayrağı: cut --complement -d ' ' -f5. Çıktıyı yeni bir dosyaya yönlendirmeyi ve ardından mvorijinalin üzerine yönlendirmeyi unutmayın .
Toby Speight

6

awk: 5. alanı kaldır

awk '{for (i=5; i<NF; i++) $i = $(i+1); NF--};1' file

Dosyayı yerinde kaydetmek istiyorsanız: /programming//q/16529716/7552

5. alanın içeriğini silebilirsiniz, ancak bu art arda 2 çıkış alanı ayırıcısı bırakır:

awk '{$5 = ""};1' file

buradaki uyarı, awk cinsinden herhangi bir alanın değerinin değiştirilmesinin, her bir alan arasında sadece 1 ayırıcı ile tüm "$ 0" ı yeniden yazmanın yan etkisi olmasıdır. Herhangi bir hizalamayı korumak istiyorsanız (gnu awk bundan kaçınmak için bir seçenek yoksa? normal awk / nawk 0 $ 'ı yeniden hesaplayacaktır) dikkate alınmalıdır
Olivier Dulac

Her iki durumda da, hattı tek bir ayırıcıyla yeniden biçimlendirirsiniz . Bir ayırıcıda 2 boşluk veya boşluk + sekme varsa, sonuç yerinde tek bir boşluktur. Bu metnin çoğu için hoppefully ok.
NeronLeVelu

4

POSIX sed ile:

sed -e 's/[^[:alnum:]_][[:alnum:]_][[:alnum:]_]*//4' <file

alnum: neden sınıfını sınırlamak ve _ değil sonra başka bir şey :blank:ya :space:?
NeronLeVelu

@NeronLeVelu: Bu, bir kelimeyi neyin oluşturduğunu nasıl tanımladığınıza bağlıdır.
cuonglm

@mikeserv; İyi yakaladın! Cevabımı güncelledim.
cuonglm

Ne var \(yakalama grubu \)için?
mikeserv

@mikeserv: yanlış yazım, sadece sınırlayıcıyı tutmanın bazı yollarını denedim.
cuonglm

2

glenn , eşdeğer bir çözüm sundu.

awk '{$ 5 = ""; yazdır} ' dosya

O ve diğerlerinin işaret ettiği gibi, bu

  1. her satırın önündeki ve sonundaki boşlukları çıkarır,
  2. boşlukların her dizesini (boşluklar ve / veya sekmeler) tek bir boşlukta sıkıştırır ve
  3. dördüncü ve altı kelime arasında iki boşluk bırakır.

Üçüncü sorunu düzeltmek için bir hack

awk '{$ 5 = ""; yazdır} ' dosya | sed 's / / /'

Bu, beş veya daha az kelime girilen herhangi bir satırın sonunda bir veya daha fazla ek boşluk bırakacaktır. Girişte hiç görünmeyecek bir kelime belirleyebiliyorsanız,

awk '{$ 5 = "tek boynuzlu at"; yazdır} ' dosya | sed 's / * tek boynuzlu at //'

bunu bile halledecek (ama yine de 1 ve 2 problemlerini bırakıyor).


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • boşluk / sekme ayırıcıya dayalı posix sed (meta sınıfı [: blank:]])
  • 5. kelimeden sonra aşağıdaki boşluğu saklayın, ancak önceki kelimeyi kaldırın

Daha sağlam (mümkün olan en uzun kalıbı alır ve *ilk sürümde ayrımı veya kelimeyi kaçırabilir) ancak biraz daha uzun bir sürüm

sed 's/^\([[:blank:]]*\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{4\}\[^[:blank:]]\{1,\}/\1/' YourFile > Output.txt

1
sed 's/[^[:blank:]]*//5'
mikeserv

@mikeserv, bu her iki çevresindeki ayırıcı tutacak sed 's/[[:blank:]*[^[:blank:]]*//5', daha iyidir. Çok iyi bir nokta. Ben sed bir varlık olarak her bir char almak şüpheliyim ama varlık olarak en büyük kesintisiz desen alır
NeronLeVelu

sed 's/[[:blank:]][^[:blank:]]*//4'5. alanı tamamen kaldıracaktır.
mikeserv

@mikeserv Hatta başlangıçta yer olmadığını varsayarsak (örnekteki gibi)
NeronLeVelu

Bu durumda, evet, bence haklısın. Genellikle böyle bir şey boş bir alan olur ve davranış doğru olur. Bu durumda, @cuonglm'in yaptığı gibi yapmalı ve her defasında sed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4'veya w / GNU / BSD / toybox seds: gibi bir kelimeye başvurduğunuzdan emin olmalısınız sed -E 's/[[:blank:]][^[:blank:]]+//4'.
mikeserv

1

Perl.

perl -ne 'print $_ =~ /^(\w+ +\w+ +\w+ +\w+ +)\w+ (.*)/,"\n"' file

1

GNU kesintisi varsayarak başka bir olasılık:

cut -d' ' -f5 --complement file.txt

-1

Perl> 5.10 kullanarak (ve tüm satırları başarıyla çıktılar : 0)): -

perl -nE '/^((\w+ +){4})\w+ *(.*)/; say $1.$3' file
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.