Bir dosyadaki son n satırı nasıl düzenleyebilirim?


10

Bir dosyadaki son n satırı düzenlememe izin verecek bir komut var mı? İçinde farklı sayıda satır bulunan birkaç dosyam var. Ancak her dosyadaki son n satırı değiştirmek istiyorum. Amaç, son n satırındaki virgüllerin yerine noktalı virgül koymaktır. Ama sadece son satırda.

Herhangi bir satırı silmek istemiyorum, sadece her virgülün her dosyadaki son n satırındaki noktalı virgülle değiştirilmesini istiyorum.

Sed komutunu kullanarak en son satırı bu komutla değiştirebiliyorum. Burada açıklandığı gibi: Bir dosyanın son satırındaki metni nasıl kaldırabilirim?

Ama bu sadece son satırı değiştirmeme izin veriyor, son satırda değil.


1
Sadece başlangıç ​​çizgisinin sed '24,$s/,/:/g' filename nerede 24olduğunu ``
Valentin Bajrami

Yanıtlar:


13

Son n satırındaki virgüllerle noktalı virgül değiştirmek için ed:

n=3
ed -s input <<< '$-'$((n-1))$',$s/,/;/g\nwq'

Bunu ayırmak:

  • ed -s = sessizce çalıştır (sonunda yazılan baytları bildirme)
  • '$-'= dosyanın sonundan ( $) eksi ...
  • $((n-1)) = n-1 satır ...
  • ( $' ... '= komutu kabuktan korumak için geri kalan komutu ver)
  • ,$s/,/;/g= ... dosyanın sonuna kadar ( ,$), tüm virgülleri arayın ve noktalı virgülle değiştirin.
  • \nwq = önceki komutu sonlandırıp kaydet ve çık

Son n satırındaki virgüllerle noktalı virgül değiştirmek için sed:

n=3
sed -i "$(( $(wc -l < input) - n + 1)),\$s/,/;/g" input

Bunu ayırmak:

  • -i = "yerinde" dosyasını düzenle
  • $(( ... )) = biraz matematik yap:
  • $( wc -l < input) = dosyadaki satır sayısını al
  • -n + 1 = geriye doğru n-1 satır
  • ,\$ = n-1 satırından dosyanın sonuna kadar:
  • s/,/;/g = virgül yerine noktalı virgül koy.

Değiştirebilir miyim wc -l < inputile wc -l input. Birkaç nanosaniye daha hızlı olmalı :)
gardenhead

1
bunun dışında wc -l inputdosya adını da verir; sadece satır sayısını istiyoruz
Jeff Schaller

Ed ile ilk tavsiye iyi ve basittir.
sku2003

Aslında tamamen farklı bir taraftan yardım aldım. Bu, bu garip kod parçasıyla sonuçlandı, bu hile yapıyor ancak uzun ve garip. Sanırım bu, bir çözümü ne zaman bir araya getireceğinizle sonuçlanabileceğiniz tuhaf şeyler. Her neyse seninki benimkinden daha güzel, daha kısa ve daha az karmaşık: Buradaki kod da işe yaradı:
sku2003

cat girişi. dosya | sed 's /, /, \ n / g' | sed -n '1! G; h; $ p' | awk -vn = 2 'NR <= n {gsub (",", ";", $ 0)} {print}' | sed -n '1! G; h; $ p' | sed '/ ^ \ s * $ / d'> output.file
sku2003

6

File.txt dosyasının son 50 satırındaki her virgülle noktalı virgül koymak için tac ve sed kullanma çözümü :

tac file.txt | sed '1,50s/,/;/g' | tac

5

GNU headve Bourne benzeri bir kabukla:

n=20
{ head -n -"$n"; tr , ';'; } < file 1<> file

Dosyanın üzerine yazıyoruz. Bu bir bayt to-byte harf çevirisi için buraya tamam ama modifikasyon dosyasının boyutunu değiştirmeden ima değilse mutlaka (bu durumda, değiştirmek istediğimiz olurdu 1<> fileile > other-file && mv other-file fileörneğin).


1
İşte1<> bilmediğim dokümanlar . Ayrıca, spongegelen moreutils size girişini üzerine yazmak istiyor boru hatları için iyi bir araçtır.
Miles

1

7Aşağıdaki sıranın son satırlarını kabuk betiği ve GNU uygulaması ile değiştirmek istediğimizi varsayalım sed:

$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Adım 1 : Sıralamanın son satır sayısını aşağıdaki gibi alalım. Bir göz atın bu ve o :

$ lastLine=`seq 20|sed -n '$='`

$ echo $lastLine 
20

2.Adım : Düzenlemek istediğimiz satır sayısını (sıralamanın sonunda) ayarlayalım:

$ numberOfLines=7

$ echo $numberOfLines 
7

Adım 3 : Başlangıç ​​çizgisini aşağıdaki gibi önceki değişkenlere göre hesaplayalım. Bir göz atın bu :

$ startLine=`expr $lastLine - $numberOfLines + 1`

$ echo $startLine 
14

Adım 4 : Şimdi, son 7 sıra dizisini aşağıdaki gibi başka bir şeyle değiştirebiliriz. Bir göz atın bu :

$ seq 20|sed -e "$startLine,+$numberOfLines{s/[12]/WoW/}"
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

Adım 4 sed man sayfasının 4.4 bölümünü kullanıyor :

'ADDR1,+N'
     Matches ADDR1 and the N lines following ADDR1.

Adım 4, burada belirtildiği gibi çift ​​tırnak işareti kullanmaktadır .


Gohu'nun cevabını böyle kullanırsak 4 adım gereksizdir :

$ seq 20 |tac|sed -e '1,7{s/[12]/WoW/}'|tac
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

0

tailSed için boru kullanın :

tail -n 20 file | sed 's/,/;/g'

Bu son 20 satır için dosya üzerinde çalışır. Eğer cange doğrudan dosya kullanımı olmasını istiyorsanız:

tail -n 20 file | sed -i 's/,/;/g'

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.