
現在、私は以下を使用しています簡略化されたコマンドに末尾の空白を削除するそしてファイルの最後に改行を追加する必要な場合:
find . -type f -exec sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' {} \+
すぐにわかるように、これには2つの問題があります。バイナリファイルそして、ファイルの末尾に改行を追加します。␍␊ 行区切りこれらの変更はコミット時に簡単に元に戻したりスキップしたりできますgit gui
が、元に戻す回数を最小限に抑えたいと考えています。そのためには、次の操作を行います。
スキップする方法はありますか?全体ファイルの場合どれでもsed
行は?内の正規表現と一致します。
* バイナリファイルには␀文字が含まれていない可能性があり、意図的に改行や␀が混在しているファイルもあることは承知しています。しかし、私は人間の介入を最小限に抑える解決策を探しています。できたおそらく、操作したいファイル拡張子をすべてリストすることになりますが、リストが非常に長くなり、常に確認する必要があり、名前の衝突によりバイナリ ファイルが漏れてしまう可能性が依然としてあります。
複雑回避策:
while IFS= read -r -d '' -u 9
do
if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
then
sed -i -e 's/[ \t]\+\(\r\?\)$/\1/;$a\' -- "$REPLY"
else
echo "Skipping $REPLY" >&2
fi
done 9< <(find . -type f -print0)
答え1
git
バイナリ ファイルかどうかに関する の見解を信頼している場合は、 を使用しgit grep
て非バイナリ ファイルのリストを取得できます。t.cpp
がテキスト ファイルで、 がls
バイナリであると仮定すると、両方ともチェックインされています。
$ ls
t.cpp ls
$ git grep -I --name-only -e ''
t.cpp
オプション-I
の意味は次のとおりです。
-I
バイナリ ファイル内のパターンを一致させないでください。
sed
これをあなたの表現と組み合わせるには:
$ git grep -I --name-only -z -e '' | \
xargs -0 sed -i.bk -e 's/[ \t]\+\(\r\?\)$/\1/;$a\'
( -z
/ はxargs -0
奇妙なファイル名に役立ちます。)
git grep
その他の便利なオプションについては、man ページを参照してください。--no-index
また、--cached
操作するファイルのセットに応じて役立つ場合もあります。
答え2
いずれかの行が sed の正規表現に一致する場合にファイル全体をスキップする方法はありますか?
はいあります。
# test case for skipping file if a sed regex match succeeds
echo 'Hello, world!' > hello_world.txt
cat hello_world.txt
ls -li hello_world.txt
sed -i -e '/.*Hello.*/{q;}; s/world/WORLD/g' hello_world.txt # skips file
sed -i -e '/.*HeLLo.*/{q;}; s/world/WORLD/g' hello_world.txt
答え3
以下は、引数 (ファイル名である必要があります) を反復処理し、改行で終わらないすべてのファイルに改行を追加する Perl スクリプトです。ヌル バイトを含むファイルはスキップされます。すでに改行で終わるファイルは変更されません。CR を含むファイルには CRLF が追加され、その他のファイルには LF のみが追加されます。テストされていません。
#!/usr/bin/env perl
foreach my $f (@ARGV) {
open F, "<", $f or die;
my $last = undef;
my $cr = 0;
while (<>) {if (/\0/) {undef $last; break} $last = $_; ++$cr if /\r$/}
close F;
if (defined $last && $last !~ /\n\Z/) {
open F, ">>", $f or die;
print($cr ? "\r\n" : "\n");
close F or die;
}
}