Sekmeleri birçok dosyadaki boşluklara dönüştürme


11

Sekmelerle dolu bir sürü dosyam var ve hepsini boşluklara dönüştürmek istiyorum. expandKomutu biliyorum , ama ne yazık ki her dosyayı kullanarak yazmak zorunda kalacaktım. Linux'ta bunu yapmanın daha kolay bir yolu var mı?

Yanıtlar:


12

Takip etmeyi dene:

find ./ -type f -exec sed -i 's/\t/ /g' {} \;

Dört boşluk istiyorsanız şunu deneyin:

find ./ -type f -exec sed -i 's/\t/    /g' {} \;

Bu, her sekmeyi tek bir boşlukla değiştirir. Kullanmaktan bahsedildiği için expand, korunan metnin hizalanmasını istediğini varsayıyorum.
garyjohn

Sen olması gerekir 's/\t/ /g'satırda bir sekme daha yerine.
Daniel Andersson

1
Çok sayıda dosya varsa önemli bir hızlanma " find ./ -type f -exec sed -i ’s/\t/ /g’ {} +" (yani " +" yerine " \;") yapıyorsa, findsürüm destekliyorsa (ve kişisel olarak olmayan herhangi bir sürümle karşılaşmadım, ancak POSIX standardı değil) , sanırım bazı sistemlerde olabilir. -exec command {} +Kılavuzdaki " " bölümüne bakın ). sedHer dosya için bir örneğini başlatmak yerine , bu, sistemin desteklediği kadar çok sayıda dosya adı bağımsız değişkeniyle (sistemimde getconf ARG_MAX= 2097152) bir argüman listesi oluşturacak xargsve böylece daha az sedişlem başlatacaktır .
Daniel Andersson

6
Bunu bulan Mac kullanıcılarına dikkat edin: OS X'in sürümü sekme çıkış sırasını sedanlamıyor \t. Kabuğa girebileceğiniz bir değişmez sekme karakteri ile değiştirebilirsiniz [Ctrl]+V, [Tab].
Jeremy Banks

expandmuhtemelen bundan daha iyidir sed: stackoverflow.com/a/11094620/131824
David Weinraub

6

Bunu yapmanın birçok yolu var. Dikkatli olmazsanız veya göründüğünüz gibi Linux'ta yeniyseniz bunu yaparken kendinizi vurmanın birçok yolu vardır. findBir editör gibi veya elle bir düzenleyici kullanarak dönüştürmek istediğiniz dosyaların bir listesini oluşturabileceğinizi varsayarsak, bu listeyi aşağıdakilere ekleyin.

while read file
do
   expand "$file" > /tmp/expandtmp
   mv /tmp/expandtmp "$file"
done

Kendinizi ayağınızdan çekmenin bir yolu, bir yazım hatası yapmaktır, böylece boş bir dosyayı belirttiğiniz tüm dosya adlarına sarar, böylece tüm dosyalarınızın içeriğini silersiniz. Bu yüzden dikkatli olun ve yedeklediğiniz küçük bir dosya kümesinde ilk yaptığınız şeyi test edin.


3
mvexpandexpand ... && mv ...
Aşağıdakilerin

expand -t 4Sekmeleri 4 aralığa genişletmeyi unutmayın . Ayrıca, bu yöntem sondaki satırsonu oluşturabilir. Ama aksi halde çalışır.
mgold

3
find . -type f -iname "*.js" -print0 | xargs -0 -I foo tab2space foo foo

-I foo her giriş satırı için bir şablon değişkeni foo oluşturur, böylece girişe birden çok kez başvurabilirsiniz.

-print0ve -0her iki komuta da SPACE yerine bir satır ayırıcı olarak \ 0 kullanmasını söyleyin, böylece bu komut boşluklu yollar için çalışır.


1
find -name \*.js -exec bash -c 'expand -t 4 "$0" | tee "$0"' {} \;

Eksileri:
boru tampon boyutundan ( 64KB ) daha büyük dosyalar kesiliyor

Artıları:
hiçbir geçici dosya
boru arabellek boyutundan daha büyük dosyalar kesilir


0

Bu daha iyi:

find . -name *.java ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

3
Bu neden daha iyi? Kullanmak harika bir fikir değil, /tmp/eçünkü o dosyayı başka bir şey kullanıyorsa, bu dosyayı bozacaktır. İki kullanıcı bunu aynı anda kullanmak istiyorsa olduğu gibi.
Kevin Panko

0

Bu sorunu aşağıdaki gereksinimleri göz önünde bulundurarak denedim:

  • Yalnızca .cpp veya .json dosyasını işlemek için dosyaları adlarına göre filtreleyin
  • Paralel işleme desteği. Çok sayıda dosya olması durumunda, bu çok büyük bir hızlanma sağlayabilir
  • Çözüm, kolay kullanım için bir hatta sığmalıdır

"Genişletme", dosyaların yerinde değiştirilmesine izin vermediğinden, son gereksinim yerine getirilmesi en zor olanıydı.

Aşağıdaki çözümü buldum:

find . -type f -regextype egrep -regex '.*\.(c|cpp|h|hpp)'  -print0 | xargs -0 -n 1 -P 10 -IFILE bash -c ' ( echo "Processing FILE..." && expand -t 4 "FILE" > /tmp/expand.$$ && mv /tmp/expand.$$ "FILE" ) || exit 255'

İşte bazı açıklamalar:

  • "find" işlenecek dosyaları bulur. "-regextype egrep", adlarına ve "egrep" biçimindeki düzenli ifadeye göre filtrelenmesine olanak tanır
  • "-type f" parametresi, örneğin dizinler veya özel bir şeyle değil, yalnızca normal dosyalarla eşleşmemizi sağlar
  • "-regexp" parametresi, bu durumda .c, .cpp, .h veya .hpp ile biten herhangi bir dosyayla eşleşen normal ifadenin kendisidir (tüm ad eşleşmelidir, bu nedenle "file.c2" eşleşmez , istediğimiz budur)
  • "-print0", standart çıktısındaki dosya yollarını, her yolun sonunda 0 karakteriyle yazdırmak için "find" komutunu verir. "Xargs" için "-0" seçeneğiyle birlikte, dönüş arabalarını içeren adların bir araçtan diğerine geçmesine izin verir (oldukça nadir bir durum olsa bile ...)
  • xargs her yol için yeni bir işlem başlatır ("-n 1"), ancak paralel olarak 10 kadar işlem yapabilir ("-P 10")
  • xargs her dosya yolunu bash betiği olan komuta iletmek için "FILE" takma adını kullanır
  • bash betiği "genişlet" i çağırır ve sonucu geçerli işlem kimliğini ($$) içeren geçici bir dosyaya kaydeder, böylece belirli bir dosyada paralel çalışan tüm işlemler farklı geçici dosyalar kullanır
  • tüm komut kalıbı (command1 && command2 && command3) kullanır, böylece herhangi bir alt komut bir hata döndürürse işlem durur
  • önceki "&&" zincirinde herhangi bir hata varsa, bash betiği, xargs'ın derhal durmasına neden olacak bir çıkış kodu 255 döndürü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.