sed 4 için 2 boşluk dönüştürmek


14

4 boşluğu 2 boşluğa nasıl dönüştürür sed? Mümkün mü?

Bunu buldum ama sekme boşluklara dönüştürür:

sed -r ':f; s|^(\t*)\s{4}|\1\t|g; t f' file

Yanıtlar:


13

Gönderdiğiniz komut dosyasında 4 * n boşluklar yalnızca sekmelerden önce geliyorsa n sekmeye dönüştürülür.

4 boşluğu 2 boşlukla değiştirmek istiyorsanız, ancak sadece girinti ile, sed ile yapmak mümkün olsa da, bunun yerine Perl'i öneriyorum.

perl -pe 's{^((?: {4})*)}{" " x (2*length($1)/4)}e' file

Sed'de:

sed -e 's/^/~/' -e ': r' -e 's/^\( *\)~    /\1  ~/' -e 't r' -e 's/~//' file

Bunun indentyerine kullanmak isteyebilirsiniz .


I gotNested quantifiers in regex; marked by <-- HERE in m/^( {4}* <-- HERE )/ at -e line 1.
eddygeek

1
@eddygeek Oh, gerçekten, bu ve birkaç hata daha. Gobbledygook'u gerçek perl kodu ile değiştirdim.
Gilles 'SO- kötü olmayı bırak'

5

Basit bir şekilde çalışmaz:

sed -r 's/ {4}/  /g'

Değilse, bazı girişleri başarısız olduğu yere gönderin.


1
Bu satırın başlangıcına dahil değildir. Oraya tutturursanız, birden fazla maç için çalışmaz. Bu yüzden aşağıda unix.stackexchange.com/a/375200/259620 adresindeyiz .
geek-merlin

2 boşluk ve 4 boşluktan oluşan bir kombinasyonunuz varsa bu işe yaramaz, çünkü ikinin iki girintisi dört olarak sayılır ...
Matt Fletcher

@aexl: Bu OP için bir gereklilik değildi
Thor

@mattfletcher: soru 4 boşluğu 2 ile değiştirmekle ilgiliydi, bu yüzden amacınızı göremiyorum
Thor

4

Yalnızca önde gelen boşluklar dönüştürülecekse:

sed 'h;s/[^ ].*//;s/    /  /g;G;s/\n *//'

Yorumlarla:

sed '
  h; # save a copy of the pattern space (filled with the current line)
     # onto the hold space
  s/[^ ].*//; # remove everything starting with the first non-space
              # from the pattern space. That leaves the leading space
              # characters
  s/    /  /g; # substitute every sequence of 4 spaces with 2.
  G; # append a newline and the hold space (the saved original line) to
     # the pattern space.
  s/\n *//; # remove that newline and the indentation of the original
            # line that follows it'

Ayrıca vim'in 'ts'ayarına ve :retabkomutuna bakın


Vim çözümünüzü kullanarak, vim ile böyle birkaç dosyayı toplu olarak düzenlemenin bir yolu var mı? Aksi takdirde bir makro oluşturmak zorunda olacağını tahmin ediyorum?
chrisjlee

Unutmayın 'ts've :retabsorunun çözümü değildir, ancak birbiriyle ilişkilidir ve genel hedefinize ulaşmanıza yardımcı olabilir. Yapabilirsin vim -- *.c, :set ts=...ve sonra :argdo retabya :argdo retab!. Ayrıca bkz. 'sw'Seçenek ve vim'in kendi girintileme özellikleri.
Stéphane Chazelas

2
sed 's/^\( \+\)\1\1\1/\1\1/' file

Önde gelen alanları aynı grubun dört örneğine bölerek çalışır (böylece hepsi eşittir) ve ardından bunları grubun yalnızca iki örneğiyle değiştirir.


Bu mevcut çözümleri nasıl geliştirir?
Philippos

1
Tek boşlukları korur, yalnızca önde gelen boşlukları etkiler, global bayrağı gerektirmez, değiştirmenin her iki tarafındaki herhangi bir sayıda alanı (veya sekmeyi) işlemek için kolayca ayarlanabilir ve daha karmaşık sed komutlarını kullanmaz. daha sıradan kullanıcılar için rahatsız edici olabilir. Birçok şeyde olduğu gibi, bunun bir gelişme olup olmadığı oldukça özneldir, ancak kendim için konuşuyorum: bunu bir senaryoda bulmak, hızlı bir şekilde grok için listelenen diğer çözümlerden bazılarından daha kolay olacaktır.
Mal

İlginç. Sorduğuma sevindim. Genellikle geri bildirimler küresel bayraktan ziyade kötü olarak kabul edilir. Ancak aynı şeyi daha taşınabilir komut dosyası ile kolayca elde edebilirsiniz (kaçınarak \+). Teşekkür ederim.
Philippos

1
sed 's/    \{2,4\}\( \{0,1\}[^ ].*\)*/  \1/g' <input

Bu sadece önde gelen boşluk dizilerini sıkıştırmalıdır.

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.