
Git Bashは、WindowsにGitをインストールしたときに得られる素晴らしいbashシェルです。 grep、sed、awk、Perl などの他の一般的な UNIX ツールが内部的にバンドルされています。ファイルコマンドはありません。
このシェルでは、DOSスタイルの行末を持つファイルを検出したいと思います。このコマンドが機能すると思われましたが、機能しません。
grep -l ^M$ *
ファイルに CR 行末の一致がない場合でも機能しません。たとえば、2つのサンプルファイルを作成しhello.unix
、追加のCRのために6文字と7文字があることをhello.dos
確認できますが、どちらのファイルも。wc
hello.unix
hello.dos
grep
$ cat hello.*
hello
hello
$ wc hello.*
1 1 7 hello.dos
1 1 6 hello.unix
2 2 13 total
$ grep -l ^M hello.*
hello.dos
hello.unix
grep
これはGit Bashの実装のバグですか? DOSスタイルの行の終わりを持つすべてのファイルを見つける他の方法はありますか?
答え1
編集:愚かな私。もちろん、^ MはCRなので、コマンドが機能する必要があります(私のシステムでは機能しました)。ただし、リテラル '\r'/CR (2 文字の^
sum ではなくM
) を取得するには、Ctrl-V Ctrl-M と入力する必要があります。
代替:
これを行う:
find dir -type f -print0 | xargs -0 grep -l `printf '\r\n'`
またはこれ:
find dir -type f -print0 | xargs -0 grep -lP '\r\n'
ファイルユーティリティを使用することもできます(GIT bashに付属しているかどうかはわかりません)。
find dir -type f -print0 | xargs -0 file | grep CRLF
答え2
私はgit bashを知りませんが、たぶん
if [ "$(tr -cd '\r' < file | wc -c)" -gt 0 ]; then
echo there are CR characters in there
fi
動作します。アイデアは使わないことですテキストCRとLF文字を特別に扱うユーティリティです。
それでもできない場合は、おそらく
if od -An -tx1 < file | grep -q 0d; then
echo there are CR characters in there
fi
フックビュー:
find . -type f -exec sh -c 'od -An -tx1 < "$1" | grep -q 0d' sh {} \; -print
答え3
@schは私を次の解決策に導きました。
sed -bne '/\r$/ {p;q}' < /path/to/file | grep -q .
ファイルにCRで終わる行がある場合はTRUEで終了します。 find に接続するには:
find /path/to/ -type f -exec sh -c 'sed -bne "/\r$/ {p;q}" < "$1" | grep -q .' sh {} \; -print
grep -l ^M hello.*
このシェルでこれがうまくいかない理由がわかります。 Git Bashでは、^M
文字がすべてのコマンドライン引数から削除され、文字がgrep
実際には受信されないため、すべてのファイルが一致しているようです。この動作は、コマンドラインだけでなくシェルスクリプトでも発生します。
したがって、文字通りの意味ではなく、^M
などの異なる記号を使用して文字を表現することが重要です。\r
答え4
Linux/Ubuntu では、file コマンドを使用します。ファイルがDOS形式の場合、出力には「CRLF行終端を使用」という単語が含まれます。ファイルがUNIX形式の場合、その単語は出力に表示されません。次の例では、del.txt は DOS 形式、del は UNIX 形式です。
$ file del.txt
del.txt: C source, ASCII text, with CRLF line terminators
$ echo "hello" > del
user@decatur2:~/manpuriav$ file del
del: ASCII text