Gedit veya komut satırı ile bir metin dosyasının her dördüncü satırını değiştirmek mümkün müdür?


11

Bir metin dosyasını sekmeyle ayrılmış bir e-tabloya dönüştürmeye çalışıyorum. Metin dosyam şöyle bir şey:

Dog
Cat
Fish
Lizard
Wolf
Lion
Shark
Gecko
Coyote
Puma
Eel
Iguana

Gedit veya LibreOffice'teki standart arama ve değiştirme işlevleriyle, satır sonunu bir sekme ile değiştirmek kolaydır. Ama sadece sekmeler için satır başını değiştirirsem, şunu alırım:

Dog   Cat   Fish   Lizard   Wolf   Lion   Shark   Gecko   Coyote   Puma   Eel   Iguana

Ama yapmam gereken şu şekilde görünmesini sağlamak:

Dog   Cat   Fish   Lizard
Wolf   Lion   Shark   Gecko  
Coyote   Puma   Eel   Iguana

Yani, her dördüncü satır dışında bir sekme için satır karakterinin her iki ucunu değiştirebilir miyim ?

Bu tür bir koşullu yinelemenin Gedit veya LibreOffice gibi bir program içinde düzenli ifadelerle yapıp yapamayacağını bilmiyorum, bu yüzden bu bir çeşit komut satırı işlevi olmalı? Başlamak için en iyi aracın ne olduğu konusunda net değilim.


Güncelleme:

Aşağıdaki komutları denedim:

sed 'N;N;N;s/\n/\t/g' file > file.tsv

paste - - - - < file > file.tsv

pr -aT -s$'\t' -4 file > file.tsv

xargs -d '\n' -n4 < inputfile.txt

Ancak ortaya çıkan tsvdosyayı LibreOffice'de açmaya çalıştığımda , sütunlar doğru değil. Bu yukarıdaki komutları doğru yürütmüyor veya LibreOffice alma işlevinde yanlış bir şey yapıyorum anlamına gelir emin değilim:

Kireç'te TSV açılması

Sadece referans için, istenen sonuç aşağıdaki gibi görünmelidir:

Uygun sütunlar

Yanıtlar:


16

Sen olabilir gibi bir komut satırı editörü kullanmaksed

sed 'N;N;N;s/\n/\t/g' file > file.tsv

veya daha programlı olarak, GNU sed'in adres operatörünü kullanarak birleştirmek istediğiniz satırların her birine ters eğik çizgi devam karakterleri ekleyerek ve devam eden satırlara katılmak n skip miçin klasik tek astarla takip ederek:

sed '0~4! s/$/\t\\/' file | sed -e :a -e '/\\$/N; s/\\\n//; ta'

Örneğin bkz. Sed One-Liners Açıklandı :

  1. Bir ters eğik çizgi "\" ile bitiyorsa bir sonrakine bir satır ekleyin.

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

Bununla birlikte, IMHO, diğer standart metin işleme yardımcı programlarından biri ile daha kolay olacaktır;

paste - - - - < file > file.tsv

(sayısı -sütun sayısına karşılık gelir) veya

pr -aT -s$'\t' -4 file > file.tsv

( -s$'\tçıktının birden çok sekmeyle ayrılmasını önemsemiyorsanız, atlayabilirsiniz ).


Gözlemlediğiniz garip yeniden içe aktarma davranışı, orijinal dosyanın Windows stili CRLF satır sonlarına sahip olması nedeniyle neredeyse kesin. Windows'taki dosyalarla çalışmanız gerekiyorsa, dönüşümü komuta dönüştürmek için çeşitli yollarla ör.

tr -d '\r' < file.csv | paste - - - -

veya

sed 'N;N;N;s/\r\n/\t/g' file.csv

Birincisi TÜM satırbaşı döndürmelerini kaldıracak, ikincisi ise yeni satırların her birinin sonunda bir CR koruyacaktır (bu, amaçlanan son kullanıcı Windows üzerindeyse istediğiniz olabilir).


1
Windows stili satır sonları hakkında bir not: bunlar ve Unix stili arasında dönüştürmek için standart araçlar dos2unixve unix2dos.
David Foerster

13

Her xargszaman, her biri tek bir boşluk bırakarak dört satırı tek bir grupta gruplamak için kullanabilirsiniz :

xargs -d '\n' -n4 < inputfile.txt

-d '\n'giriş sınırlayıcıyı yeni satır karakterine ayarlar, aksi takdirde boşluklara da zarar verir. Yine de her giriş satırı için yalnızca bir kelimeniz varsa, bunu bile atlayabilirsiniz.
-n4bağımsız değişken numarasını (çıktı satırı başına girdi öğesi sayısı) 4 olarak ayarlar.

Çıktı:

Dog Cat Fish Lizard
Wolf Lion Shark Gecko
Coyote Puma Eel Iguana

Veya sekmeleri boşluk yerine ayırıcı olarak istiyorsanız, daha sonra değiştirebilirsiniz. Ancak, giriş satırlarınızda boşluklar varsa, bunlar da değiştirilir:

xargs -d '\n' -n4 | tr ' ' '\t'

Çıktı (tarayıcı / terminalin sekme genişliğine bağlı olarak bakın):

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana

Bu yöntem, toplam girdi satırı sayısı dördün katı olmasa bile makul davranması avantajına sahiptir.
Eliah Kagan

3

Ayrıca şunları kullanabilirsiniz:

awk -v ORS="" '{print $1; print NR%4==0?"\n":"\t"}' file > file.tsv 

İki awk yerleşik değişkeni:

  • ORS: O ıkış R üzerindeki Record S eparator (varsayılan = satır). Her yazdırma komutunun sonuna eklenir.
  • NR: K akımın toprak rengi R awk'ın akış işleme.

Bu komut, her satır için ilk (ve yalnızca burada) sütunun içeriğini görüntüler. Ardından, bölümünün kalanını NR4'e kadar test ederek bir satırsonu veya sekme eklemeyi seçer .


3

Başka bir kısa awkyaklaşım:

awk '{printf $0 (NR%4?"\t":"\n")}' infile

Bu Printf tek sütun sonraki ve bir sonraki ve ... ve bir sekme izledi \ther sonrasında karakteri ama olacak printf bir \nzaman ewline karakterini N ait toprak rengi R üzerindeki Record faktör oldu 4 ( NR%4dönecektir 0 neyi Üçlü Operatör olduğunu (false) condition(s)?when-true:when-falseyapıyor.)


3

Bu Benim çözüm kombinasyonunu kullanmak olacaktır sedve sed. İlk olarak, her dördüncü satırı özel bir karakterle işaretleyebilirsiniz, örneğin >, bu çözümü kullanarak:

Bu durumda 5. satırdan başlamak ve her 4. satırdan sonra işaretlemek istersiniz. GNU'da sedadres olarak verilebilir 5~4. Bu komutu kullanabilirsiniz:

sed '5~4s/^/>/' file1 > file2

Ardından, bir seddöngü ile yapılabilen yeni satırları kaldırmanız gerekir :

sed ':a;N;s/\n/ /;ba' file2 > file3

Yeni satırları başka bir karaktere dönüştürmenin daha kolay yolları vardır, örneğin tr:

tr '\n' ' ' < file2 > file3

Her iki durumda da, iki

Dog   Cat   Fish   Lizard   >Wolf   Lion   Shark   Gecko   >Coyote   Puma   Eel   Iguana

( sedsürüm sondaki yeni satırdan ayrılır, trsürüm içermez)

Bundan sonra, yalnızca eklediğiniz özel karakterleri yeni satırlara dönüştürmeniz gerekir; bkz. sekme ile ayrılmış bir dosyayı yeni satırlar kullanmak için dönüştürme . Bu durumda, >yeni satırlara geçin:

sed 'y/>/\n/' file3 > outfile

yKomut aynı işlevi yerine trbaşka bir bir karakter dönüştürme, ancak kullanabilirsiniz seşit derecede iyi burada komutu. İle s, gsatırdaki her maçta ( sed 's/>/\n/g') işlem yapmanız gerekir .

İki ara dosya yapmak yerine, boruları kullanabilirsiniz:

$ sed '5~4s/^/>/' file | sed ':a;N;s/\n/ /;ba' | sed 'y/>/\n/'
Dog Cat Fish Lizard 
Wolf Lion Shark Gecko 
Coyote Puma Eel Iguana

Sondaki boşluklar bir sorunsa, bunları kaldırmak için başka bir komut ekleyebilirsiniz:

| sed 's/ $//'

2

"Tamlık" uğruna işte saf bir bash çözümü:

#!/usr/bin/env bash

sep=$'\t'

while read one \
      && read two \
      && read three \
      && read four
do
  printf "%s\n" "$one$sep$two$sep$three$sep$four"
done

Alanlarla da çalışır IFS, düzgün ayarlandığı varsayılarak (varsayılan olarak AFAIK olması gerekir). Ayrıca, bu bile taşınabilir bir kabuk komut dosyası olabilir ve herhangi bir POSIX uyumlu kabuk ile çalışabilir düşünüyorum .


1
Bu, POSIX uyumlu kabuklara taşınabilir değildir, çünkü $' 'POSIX tarafından alıntılama şekli gerekli değildir. Örneğin, dash( shvarsayılan olarak Ubuntu'da sağlar), printf '%s\n' $'a\tb'yalnızca çıktıları çalıştırır $a\tb. Bu, bunun yararlı olmadığı anlamına gelmez; bash'da çalışıyor. Bununla birlikte, insanların gönderdiği diğer bazı çözümlerde olduğu gibi, girdi satırlarının sayısı dördün katı değilse, eksik çıktı üretir. Ayrıca, kullanmanızı öneririz read -r, çünkü burada giriş dosyasındaki ters eğik çizgi kaçışlarının genişlemesinin istendiğini düşünmek için bir neden yoktur.
Eliah Kagan

Basitçe yapabilirsinprintf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$four"
terdon

2

Bir vim makrosu (q ile kaydedilmiş) işleminizi uygulayabilir, ardından üç satırı atlayabilir. Ardından, bu makroyu n kez çalıştırırsınız.

Örneğin:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q

2

Bir Gedit çözümü istediğinden, böyle bir şey işe yarayacaktır:

bul:

(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+

Şununla değiştir:

\1\t\2\t\3\t\4\n

Normal ifadeler için onay kutusunun işaretli olduğundan emin olun.

Nasıl çalışır:

İlk adım \ w + ile bir dizi kelime karakteri bulmak ve parantezleri ifadenin etrafına sararak \ 1 değişkenindeki sonuçları yakalamaktır:

(\w+)

Daha sonra \ r ve \ n veya CR ve LF gibi bir dizi satır sonu karakteri ararız. Windows biçimli dosyalar her ikisini de kullandığından, bu iki karakteri köşeli parantez içine alarak bir karakter sınıfı oluştururuz. Artı, bir veya daha fazla karakter aramasını sağlar:

[\r\n]+

Son olarak, bunu sonraki 2 kelimeyi \ 2, \ 3 ve \ 4 değişkenlerine kaydederek 3 kez daha tekrarlıyoruz. Bu, ifadeyle değiştirmemizi kolaylaştırır. Sekme karakterlerini \ t ve yeni bir çizgi karakterini \ n, ihtiyacınız olan biçimlendirme için uygun yerlere yerleştirmemiz gerekir.

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.