Tüm dosyaların sonundaki boşlukları yinelemeli olarak nasıl kaldırılır?


122

Tüm bir projenin arkasındaki tüm boşlukları nasıl kaldırabilirsiniz? Bir kök dizinden başlayarak ve sondaki beyaz boşluğu tüm klasörlerdeki tüm dosyalardan kaldırarak.

Ayrıca, dosyayı doğrudan değiştirebilmek ve sadece her şeyi standart çıktıya yazdırmak istemiyorum.


Oh, "taşınabilir" bir çözüm mü, yoksa daha işletim sistemine özgü bir çözüm mü arıyorsunuz? Hangi işletim sistemini kullanıyorsunuz?
Joe Pineda

3
Bunun OS X Snow Leopard üzerinde çalışacak ve .git ve .svn klasörlerini yok sayacak bir sürümünü görmek isterim.
Trevor Turk

Yanıtlar:


83

İşte bir OS X> = 10.6 Snow Leopard çözümü.

.Git ve .svn klasörlerini ve içeriklerini yok sayar . Ayrıca bir yedekleme dosyası bırakmaz.

export LC_CTYPE=C
export LANG=C
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"

10
Yerini alan dizge \+yerine kullanarak daha hızlı hale getirebilirsiniz *- Aksi takdirde her satırda eşleşir.
l0b0

10
Hem sekmeleri hem de boşlukları kaldırmak için [[: blank:]] kullanabilirsiniz.
Leif Gruenwoldt

21
Mountain Lion'da bu sed: RE error: illegal byte sequencebenim için geri dönüyor .
Bryson

12
"Yasadışı bayt dizisi" ile sorunları olanlar için: Girin export LANG=Cve tekrar deneyin
Georg Ledermann

3
OS X export LC_CTYPE=C
10.9'da

31

kullanın:

find . -type f -print0 | xargs -0 perl -pi.bak -e 's/ +$//'

".bak" dosyalarının oluşturulmasını istemiyorsanız:

find . -type f -print0 | xargs -0 perl -pi -e 's/ +$//'

zsh kullanıcısı olarak bulmak için aramayı atlayabilir ve bunun yerine şunu kullanabilirsiniz:

perl -pi -e 's/ +$//' **/*

Not: yok önlemek için .gitdizin eklemeyi deneyin: -not -iwholename '*.git*'.


37
Git'in dahili depolamasını bozabileceğinden bunu bir git deposunda denemeyin.
mgold

11
@mgold Çok geç, grrr; /
kenorb

3
Açıklığa kavuşturmak gerekirse, bunu bir git deposunun bir alt klasöründe çalıştırmak sorun değil, sadece git deposu / altlarını içeren klasörlerin içinde değil, yani dizinleri olan klasörlerin içinde .git, ne kadar derinlemesine iç içe geçmiş olursa olsun.
Illya Moskova

Git / svn sorunlarını önlemek için bu yanıtı @ deepwell's ile birleştirmekfind . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
William Denniss

1
Muhtemelen daha iyi bir yol var, ancak bununla bir git deposunu karıştırmaktan, depoyu ayrı bir klasörde klonlayarak ve ardından rsync -rv --exclude=.git repo/ repo2/yerel değişikliklerin repode (hasarsız) içinde olduğunu yaparak kurtuldum repo2.
MatrixManAtYrService

29

DOS satırsonları (CR / LF) ile de çalışan ve ikili dosyalardan kaçınmada oldukça iyi bir iş çıkaran iki alternatif yaklaşım :

MIME türünün aşağıdakilerle başladığını kontrol eden genel çözümtext/ :

while IFS= read -r -d '' -u 9
do
    if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
    then
        sed -i 's/[ \t]\+\(\r\?\)$/\1/' -- "$REPLY"
    else
        echo "Skipping $REPLY" >&2
    fi
done 9< <(find . -type f -print0)

Git'in ikili olarak kabul ettiği dosyaları atlama-Iseçeneğinikullanan Mat tarafından geliştirilen Git havuzuna özgü çözümügit grep :

git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$/\1/'

3
Bu yüzden bu git çözümünü gerçekten beğendim. Gerçekten en üstte olmalı. Yine de vagon iadelerini kaydetmek istemiyorum. Ama bunu 2010'da birleştirdiğim yerine tercih ediyorum.
odinho - Velmont

Benim git -e ifade boş, ama -e kullanarak büyük çalıştığını şikayet '*.'
muirbot

@okor GNU sedson ek seçenek -iise isteğe bağlı , ancak BSDsed değil. Burada kesinlikle gerekli değil, bu yüzden onu kaldıracağım.
l0b0

24

Bash'de:

find dir -type f -exec sed -i 's/ *$//' '{}' ';'

Not: kullanıyorsanız .gitdepo eklemeyi deneyin: -not -iwholename '.git'.


Bu, bulunan her dosya için buna benzer hatalar oluşturur. sed: 1: "dir / file.txt": komut a bekliyor \ ve ardından metin
iamjwc

';' Değiştiriliyor ile \; çalışmalı. (Ayrıca {} ile ilgili alıntılara kesinlikle gerek yoktur).
agnul

4
Sadece boşlukları değil tüm boşlukları kaldırmak için sed normal ifadenizde boşluk karakterini [: boşluk:] ile değiştirmelisiniz.
WMR

Başka bir not: Bu yalnızca sed sürümleri> = 4 ile çalışır, daha küçük sürümler yerinde düzenlemeyi desteklemez.
WMR

1
Bu benim
gitmemi

14

Bu benim için GNU sed veya xargs kullanmayan OSX 10.5 Leopard'da çalıştı.

find dir -type f -print0 | xargs -0 sed -i.bak -E "s/[[:space:]]*$//"

Dışarıda bırakılması gereken dosyalarınız varsa buna dikkat edin (ben yaptım)!

Belirli dizinleri veya dosyaları yok saymak için -prune kullanabilirsiniz. Bir git deposundaki Python dosyaları için aşağıdaki gibi bir şey kullanabilirsiniz:

find dir -not -path '.git' -iname '*.py'

Bunu açıklığa kavuşturma şansın var mı? Sondaki beyaz boşluğu bir dizindeki tüm dosyalardan özyinelemeli olarak kaldırırken, ".git" dizinini yok sayan bir komut istiyorum.
Trevor Turk

Tcsh kullanıyorsanız, çift tırnak işaretlerini tek tırnak olarak değiştirmeniz gerekir. Aksi takdirde, bir "Geçersiz değişken adı" alırsınız. hata.
Brandon Fosdick

GNU sed benzerdir, ancak -i.bak veya --in-place = .bak yaparsınız, tam bir komutla biter find dir -not -path '.git' -iname '*.py' -print0 | xargs -0 sed --in-place=.bak 's/[[:space:]]*$//'. Tekrarlanacak diren üst düzey olarak söz konusu dizini değiştirin .
David Gardner

sed -i .bak? Olması gerekmez mi sed -i.bak(boşluksuz)?
Ondra Žižka

9

Bu tür bir görev için onay verildi.

Tıpkı grep gibi çalışır, ancak .svn, .git, .cvs vb. Yerlere inmemesi gerektiğini bilir.

ack --print0 -l '[ \t]+$' | xargs -0 -n1 perl -pi -e 's/[ \t]+$//'

Find / grep ile çemberlerden atlamaktan çok daha kolay.

Ack, çoğu paket yöneticisi aracılığıyla ( ack veya ack-grep olarak ) kullanılabilir.

Bu sadece bir Perl programı, yani indirip çalıştırabileceğiniz tek dosyalık bir sürümde de mevcuttur. Bakınız: Ack Install


ackharika. Birkaç yıldır kullanılıyor ve çoğu dağıtım için neredeyse tüm paket depolarında mevcut.
Felipe Alvarez

8

ex

Ex düzenleyiciyi kullanmayı deneyin (Vim'in bir parçası):

$ ex +'bufdo!%s/\s\+$//e' -cxa **/*.*

Not: Özyineleme (bash4 & zsh) için, yeni bir globbing seçeneği ( **/*.*) kullanıyoruz. Tarafından etkinleştirin shopt -s globstar.

Aşağıdaki işlevi şuraya ekleyebilirsiniz .bash_profile:

# Strip trailing whitespaces.
# Usage: trim *.*
# See: https://stackoverflow.com/q/10711051/55075
trim() {
  ex +'bufdo!%s/\s\+$//e' -cxa $*
}

sed

Kullanmak için sedkontrol edin: Sondaki beyaz boşluklar sed ile nasıl kaldırılır?

find

remove_trail_spaces.shDosyalardan sondaki beyaz boşlukları kaldırmak için aşağıdaki komut dosyasını (örneğin ) bulun :

#!/bin/sh
# Script to remove trailing whitespace of all files recursively
# See: /programming/149057/how-to-remove-trailing-whitespace-of-all-files-recursively

case "$OSTYPE" in
  darwin*) # OSX 10.5 Leopard, which does not use GNU sed or xargs.
    find . -type f -not -iwholename '*.git*' -print0  | xargs -0 sed -i .bak -E "s/[[:space:]]*$//"
    find . -type f -name \*.bak -print0 | xargs -0 rm -v
    ;;
  *)
    find . -type f -not -iwholename '*.git*' -print0 | xargs -0 perl -pi -e 's/ +$//'
esac

Bu komut dosyasını taramak istediğiniz dizinden çalıştırın. OSX'te sonunda, ile biten tüm dosyaları kaldıracaktır .bak.

Ya da sadece:

find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;

Spring Framework Kod Stili tarafından önerilen yöntemdir .


find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;tümü yerine yalnızca bir sondaki boşluğu kaldırır.
Karl Richter

6

Bul özelliğini kullanmama ve yedekleme dosyalarını oluşturmamaya son verdim.

sed -i '' 's/[[:space:]]*$//g' **/*.*

Dosya ağacının derinliğine bağlı olarak bu (daha kısa versiyon) ihtiyaçlarınız için yeterli olabilir.

NOT Bu, örneğin ikili dosyaları da alır.


Belirli dosyalar için: bulun. -name '* .rb' | xargs -I {} sed -i '' 's / [[: boşluk:]] * $ // g' {}
Gautam Rege

Sed için '' parametresine ihtiyacınız yoktur; ya da bir şey eksik olabilir. Bunu belirli bir dizindeki tüm dosyalarda denedim, şöyle: sed -i 's / [[: space:]] * $ // g' util / *. M
Mircea

6

Dosyaları hariç tutmak yerine, yukarıda açık bir şekilde beyaz listelerin bir varyasyonu, soymak istediğiniz dosya uzantısına dayalı olarak, tatmaktan çekinmeyin:

find . \( -name *.rb -or -name *.html -or -name *.js -or -name *.coffee -or \
-name *.css -or -name *.scss -or -name *.erb -or -name *.yml -or -name *.ru \) \
-print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"

Bunun benim için işe yaraması için alıntı -name "*.rb*"
eklemem

5

Pojo ve Adams versiyonunun karışımı olan bunu çalıştırdım.

Hem sondaki beyaz boşluğu hem de sondaki başka bir beyaz boşluğu temizleyecektir: satır başı:

find . -not \( -name .svn -prune -o -name .git -prune \) -type f \
  -exec sed -i 's/[:space:]+$//' \{} \;  \
  -exec sed -i 's/\r\n$/\n/' \{} \;

Varsa .git klasörüne dokunmaz.

Düzenleme : Yorumdan sonra biraz daha güvenli hale getirildi, ".git" veya ".svn" olan dosyaların alınmasına izin verilmez. Ama, dikkat edecek bazı var eğer ikili dosyaları dokunun. Yalnızca ör. .Py ve .php-dosyalarına dokunmasını istiyorsanız -iname "*.py" -or -iname "*.php"sonra kullanın -type f.

Güncelleme 2 : Artık satırın sonundaki her tür boşluğun yerini alıyor (bu da sekmeler anlamına geliyor)


4
Neler olduğunu bilmiyorum ama bu, git depomu tamamen kapattı ve resimlerimi karıştırdı. İNSANLAR, BENİMDEN DAHA DİKKATLİ OLUN!
mattalxndr

Evet, ikili dosyaları mahvedecek. Ancak, git deponuza hiç dokunmamalıdır, çünkü bir .git klasöründe bulunanları atlar. Ama belki sadece aynı klasördeyseniz.
odinho - Velmont

4

Bu iyi çalışıyor .. belirli dosya türleri için add / remove --include:

egrep -rl ' $' --include *.c *  | xargs sed -i 's/\s\+$//g'

4

Yakut:

irb
Dir['lib/**/*.rb'].each{|f| x = File.read(f); File.write(f, x.gsub(/[ \t]+$/,"")) }

3

Normal ifadeler kullanıyorum. 4 adım:

  1. Editörünüzde kök klasörü açın (Visual Studio Code kullanıyorum).
  2. Soldaki Ara simgesine dokunun ve normal ifade modunu etkinleştirin.
  3. Arama çubuğuna "+ \ n" ve Değiştir çubuğuna "\ n" girin.
  4. "Tümünü Değiştir" i tıklayın.

Bu, tüm dosyalarda her satırın sonundaki tüm boşlukları kaldırır. Ve bu ihtiyaca uymayan bazı dosyaları dışarıda bırakabilirsiniz.


2

1) Diğer birçok cevap kullanır -E. Belgelenmemiş BSD uyumluluk seçeneği olduğu için neden olduğundan emin değilim .-rbunun yerine kullanılmalıdır.

2) Diğer cevaplar kullanılır -i ''. Bu sadece -i(veya -i''tercih edilirse) olmalıdır, çünkü-i hemen sonrasında son ek vardır.

3) Git'e özel çözüm:

git config --global alias.check-whitespace \
'git diff-tree --check $(git hash-object -t tree /dev/null) HEAD'

git check-whitespace | grep trailing | cut -d: -f1 | uniq -u -z | xargs -0 sed --in-place -e 's/[ \t]+$//'

İlki check-whitespace, dosyaları sondaki boşluklarla listeleyen bir git takma adı kaydeder . İkincisi çalışırsed onlara .

Tipik olarak dikey sekmeler, form beslemeleri ve bölünemez alanlar görmediğim için \tdeğil, yalnızca kullanıyorum [:space:]. Ölçümünüz değişebilir.


1

Benim için işe yarayan şey bu (Mac OS X 10.8, Homebrew tarafından yüklenen GNU sed):

find . -path ./vendor -prune -o \
  \( -name '*.java' -o -name '*.xml' -o -name '*.css' \) \
  -exec gsed -i -E 's/\t/    /' \{} \; \
  -exec gsed -i -E 's/[[:space:]]*$//' \{} \; \
  -exec gsed -i -E 's/\r\n/\n/' \{} \;

Sondaki boşluklar kaldırıldı, sekmeleri boşluklarla değiştirdi, Windows CRLF'yi Unix ile değiştirdi \n .

İlginç olan, tüm dosyalar düzeltilmeden önce, tüm temizleme gsedtalimatlarına göre bunu 3-4 kez çalıştırmam gerektiğidir .

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.