すべてのファイルの末尾の空白を再帰的に削除する方法は?


122

プロジェクト全体の末尾の空白をすべて削除するにはどうすればよいですか?ルートディレクトリから開始し、すべてのフォルダ内のすべてのファイルから末尾の空白を削除します。

また、すべてをstdoutに出力するだけでなく、ファイルを直接変更できるようにしたいと考えています。


ああ、あなたは「ポータブルな」ソリューション、またはもっとOS固有のものを探していますか?どのOSを使用していますか?
ジョーピネダ

3
OS X Snow Leopardで動作し、.gitおよび.svnフォルダーを無視するバージョンを確認したいです。
Trevor Turk

回答:


83

OS X> = 10.6 Snow Leopardソリューションです。

.gitおよび.svnフォルダーとその内容は無視されます。また、バックアップファイルは残りません。

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
置換文字列の\+代わりにを使用することで、処理速度を上げることができ*ます。それ以外の場合は、すべての行で一致します。
l0b0

10
[[:blank:]]を使用して、タブとスペースの両方を削除できます。
Leif Gruenwoldt 2012年

21
マウンテンライオンでは、これがsed: RE error: illegal byte sequence私に返ってきます。
ブライソン2013

12
「不正なバイトシーケンス」に関する問題がある場合:入力export LANG=Cしてもう一度お試しください
Georg Ledermann

3
また、必要に応じてOS X 10.9 Iでexport LC_CTYPE=C :ここに見られるようなstackoverflow.com/questions/19242275/...
kissgyorgy

31

使用する:

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

「.bak」ファイルを生成したくない場合:

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

zshユーザーとして、findの呼び出しを省略して、代わりに次を使用できます。

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

注:.gitディレクトリの破壊を防ぐには、以下を追加してください-not -iwholename '*.git*'


37
gitの内部ストレージが破損する可能性があるため、gitリポジトリでこれを試さないでください。
mgold 2014

11
@mgold遅すぎる、grrr; /
kenorb 2015

3
明確にするために、これをgit repoのサブフォルダー内で実行し、子孫としてgit repo(s)を含むフォルダー内では.gitなく、ネストの深さに関係なく、ディレクトリを持つフォルダー内では実行しないでください。
Illya Moskvin 2016年

この回答を@deepwellと組み合わせてgit / svnの問題を回避するfind . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
William Denniss 2017

1
おそらくもっと良い方法がありますが、別のフォルダーにレポを複製してgitレポをマングルすることから回復しました。その後rsync -rv --exclude=.git repo/ repo2/、ローカルの変更repoも(破損していない)にありましたrepo2
MatrixManAtYrService

29

DOS改行(CR / LF)でも機能し、バイナリファイル回避する上で非常に優れた2つの代替アプローチ:

MIMEタイプが次で始まることを確認する一般的なソリューションtext/

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)

バイナリと見なされるファイルをスキップする-Iオプションを使用するMatによる Gitリポジトリ固有のソリューションgit grep

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

3
だから私はこのgitソリューションが本当に好きです。本当に一番上になるはずです。キャリッジリターンは節約したくありません。しかし、私は2010年に組み合わせる1のIにこれを好む
odinho - Velmont

私のgitは-e式が空であると不平を言っていますが、-e '。*'を使用するとうまく機能します
muirbot

@okor GNU sedではtoの接尾辞オプション-iオプションですが、BSDsedではそうではありません。とにかくここでは厳密に言う必要はないので、削除します。
l0b0 2014年

24

バッシュで:

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

注:.gitリポジトリを使用している場合は、以下を追加してみてください-not -iwholename '.git'


これにより、見つかったすべてのファイルに対してこのようなエラーが発生します。sed:1: "dir / file.txt":コマンドaは\の後にテキストが続くことを期待しています
iamjwc

「;」を置き換える \; うまくいくはずです。(また、{}を囲む引用符は厳密には必要ありません)。
更新

4
スペースだけでなくすべての空白を削除するには、sed正規表現でスペース文字を[:space:]に置き換える必要があります。
WMR

もう1つの注意事項:これは、sedバージョンが4以上の場合にのみ機能します。それよりも小さいバージョンは、インプレース編集をサポートしていません。
WMR

1
これは私のgitを壊しました:(
CrabMan

14

これは、GNU sedやxargsを使用しないOSX 10.5 Leopardで私にとってはうまくいきました。

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

除外する必要があるファイルがある場合は注意してください(私は除外しました)。

-pruneを使用して、特定のディレクトリまたはファイルを無視できます。gitリポジトリ内のPythonファイルの場合、次のようなものを使用できます。

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

これを明らかにできる可能性はありますか?「.git」ディレクトリを無視して、ディレクトリ内のすべてのファイルから末尾の空白を再帰的に削除するコマンドが欲しいのですが。私はあなたの例に完全に従うことはできません...
Trevor Turk

tcshを使用している場合は、二重引用符を単一引用符に変更する必要があります。それ以外の場合は、「無効な変数名」を取得します。エラー。
Brandon Fosdick、

GNU sedも同様ですが、-i.bakまたは--in-place = .bakを実行すると、完全なコマンドfind dir -not -path '.git' -iname '*.py' -print0 | xargs -0 sed --in-place=.bak 's/[[:space:]]*$//'dir再帰する最上位として、問題のディレクトリに置き換えます。
David Gardner

sed -i .bak?それはsed -i.bak(スペースなしで)すべきではありませんか?
OndraŽižka

9

Ackはこの種のタスクのために作られました。

これはgrepと同じように機能しますが、.svn、.git、.cvsなどの場所に移動しないことを認識しています。

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

find / grepでフープをジャンプするよりもはるかに簡単です。

Ackは、ほとんどのパッケージマネージャを介して(ackまたはack-grepとして)使用できます。

これは単なるPerlプログラムなので、ダウンロードして実行できる単一ファイルバージョンでも利用できます。参照:Ackインストール


ack素晴らしいです。何年にもわたって使用しており、ほとんどのディストリビューションのほぼすべてのパッケージリポジトリで利用できます。
Felipe Alvarez

8

ex

Exエディター(Vimの一部)を使用してみます。

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

注:再帰(bash4およびzsh)の場合、新しいグロビングオプション**/*.*)を使用します。によって有効にしshopt -s globstarます。

次の関数をに追加できます.bash_profile

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

sed

を使用するにはsed、以下を確認してください:sedで末尾の空白を削除するには?

find

remove_trail_spaces.shファイルから末尾の空白を削除するための次のスクリプト(例:)を見つけます。

#!/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

スキャンするディレクトリからこのスクリプトを実行します。最後のOSXでは、で終わるすべてのファイルが削除されます.bak

あるいは単に:

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

これは、Spring Framework Code Styleが推奨する方法です。


find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;すべてではなく、末尾のスペースを1つだけ削除します。
カールリヒター

6

検索を使用せず、バックアップファイルを作成しませんでした。

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

ファイルツリーの深さによっては、これ(短いバージョン)で十分な場合があります。

注:これには、たとえばバイナリファイルも含まれます。


特定のファイルの場合:検索。-name '* .rb' | xargs -I {} sed -i '' 's / [[:space:]] * $ // g' {}
Gautam Rege

sedには ''パラメータは必要ありません。または何かが足りないかもしれません。次のように、指定したディレクトリのすべてのファイルで試してみました。sed-i 's / [[:space:]] * $ // g' util / *。m
Mircea

6

ファイルを除外する代わりに、上記のバリエーションを以下に示します。これらは、ファイル拡張子に基づいて、削除するファイルを明示的にホワイトリストにしたもので、自由に味付けして試してみてください。

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:]]*$//"

これを機能させるには、引用符を追加する必要がありました-name "*.rb*"
。– haroldcarr

5

私はこれを実行しましたが、これはpojoバージョンとadamsバージョンのミックスです。

末尾の空白と、末尾の空白の別の形式であるキャリッジリターンの両方を削除します。

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

.gitフォルダーがある場合、それは触れません。

編集:コメントの後に少し安全になり、「。git」または「.svn」が含まれているファイルを取得できなくなりました。しかし注意してください、あなたがいくつかを持っているなら、それバイナリファイルに触れます。.pyや.php-filesだけに触れたい場合は-iname "*.py" -or -iname "*.php"、後で使用し-type fます。

Update 2:行末のすべての種類のスペースを置き換えます(つまり、タブも意味します)。


4
何が起こっているのかはわかりませんが、これは私のgitリポジトリを完全に混乱させ、画像をめちゃくちゃにしました。人々は、私よりももっと注意深く!
mattalxndr

はい、バイナリファイルが破壊されます。ただし、.git-folder内にあるものはすべてスキップされるため、gitリポジトリにまったく触れないでください。ただし、同じフォルダにいる場合のみです。
odinho-ヴェルモント

4

これはうまく機能します。特定のファイルタイプに対してadd / remove --includeを実行します。

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

4

ルビー:

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

3

正規表現を使用しています。4つのステップ:

  1. エディターでルートフォルダーを開きます(私はVisual Studio Codeを使用しています)。
  2. 左側の検索アイコンをタップして、正規表現モードを有効にします。
  3. 検索バーに「+ \ n」、置換バーに「\ n」と入力します。
  4. 「すべて置換」をクリックします。

これにより、すべてのファイルの各行の末尾にある末尾のスペースがすべて削除されます。また、このニーズに合わないファイルを除外することもできます。


2

1)他の多くの回答が使用しています-Eドキュメントに記載されていないBSD互換性オプションであるため、理由はわかりません。-r代わりに使用する必要があります。

2)その他の回答はを使用します-i ''。直後にサフィックスが付いているので、それは-i(または-i''優先される場合)-i正しいはずです。

3)Git固有のソリューション:

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]+$//'

最初のものcheck-whitespaceは、末尾の空白を含むファイルをリストするgitエイリアスを登録します。2つ目sedはそれらで実行されます。

私はのみを使用\tするのではなく[:space:]、私は通常、垂直タブ、フォームフィードと非破壊可能なスペースが表示されていないよう。測定値は異なる場合があります。


1

これは私にとってうまくいくものです(Mac OS X 10.8、Homebrewによってインストールされた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/' \{} \;

末尾のスペースを削除し、タブをスペースに置き換え、Windows CRLFをUnixに置き換えます\n

興味深いのは、すべてのクリーニングgsed手順によって、すべてのファイルが修正される前にこれを3〜4回実行する必要があることです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.