Edited at

カレントディレクトリ以下で改行コードがCR+LFのファイルを探す

More than 5 years have passed since last update.

Linux または Cygwin でカレントディレクトリ以下で改行コードがCR+LFのファイルを探すには以下ようにします。


やり方1

grep を使う方法です。grep にファイル名だけを表示する -l を指定しています。

(このやり方ではバイナリファイルも結果に含めてしまいますが、例2のように拡張子を指定すればより意味のある検索になるかもしれません)


追記(2014/06/23 19:10): CR+LFの検出を意図していましたが、現状以下のコマンドではCRのみの場合にもヒットしてしまいます。良い方法が見つかったら修正します。良い方法が見つかったので修正しました。

追記(2014/06/24 15:25): elfmimi さんが見つけてくれた方法で、CR+LFを検出することができました。



例1

$ find . -type f | xargs grep -lzUP '\r\n'



例2

$ find . -name "*.java" | xargs grep -lzUP '\r\n'



やり方2

とりあえず、C言語でコマンドを自作して対処 (^ー^); というのは…どうでしょうかw

(このやり方ではでもバイナリファイルも結果に含めてしまいます)


使い方

$ gcc -o /usr/local/bin/crlf crlf.c

$ find . -type f | xargs crlf


crlf.c

#include <stdio.h>


int main(int argc, char **argv)
{
if(argc < 2) return 1;
int i;
for(i=1; i<argc; i++)
{
FILE *fp = fopen(argv[i], "r");
if(!fp) continue;
int last = 0;
int c = 0;
while((c=fgetc(fp)) != EOF)
{
if(last=='\r' && c=='\n')
{
printf("%s\n", argv[i]);
break;
}
last=c;
}
fclose(fp);
}
return 0;
}


やり方3

Linux (or Cygwin) の file コマンドを実行した際の出力(標準出力)を取り出して、"with CRLF line terminators" が含まれていたらファイル名を出力するという方法です。バイナリファイルを対象外とすることができます。

(シェルでやる前に、とりあえずC言語のコマンドを使って実現してみました)


使い方

$ gcc -o /usr/local/bin/textcrlf textcrlf.c

$ find . -type f | xargs textcrlf


textcrlf.c

#include <stdio.h>

#include <string.h>
#define MAXLEN (1024)

int main(int argc, char **argv)
{
if(argc < 2) return 1;
int i;
for(i=1; i<argc; i++)
{
static char cmd[MAXLEN];
sprintf(cmd, "file %s", argv[i]);
FILE *fpin = popen(cmd, "r");
if(!fpin) continue;
static char line[MAXLEN];
if(!fgets(line, MAXLEN, fpin))
{
pclose(fpin);
continue;
}
if(strstr(line, "with CRLF line terminators"))
{
printf("%s\n", argv[i]);
}
pclose(fpin);
}
return 0;
}


番外編

Linux (or Cygwin) で改行コードが LF のファイルを見つけるC言語のコマンドも作ってみました。

このコマンドも file コマンドの出力に依存しています。


使い方

$ gcc -o /usr/local/bin/textlf textlf.c

$ find . -type f | xargs textlf


textlf.c

#include <stdio.h>

#include <string.h>
#define MAXLEN (1024)

int main(int argc, char **argv)
{
if(argc < 2) return 1;
int i;
for(i=1; i<argc; i++)
{
static char cmd[MAXLEN];
sprintf(cmd, "file %s", argv[i]);
FILE *fpin = popen(cmd, "r");
if(!fpin) continue;
static char line[MAXLEN];
if(!fgets(line, MAXLEN, fpin))
{
pclose(fpin);
continue;
}
if(strstr(line, "with CR line terminators"))
{
;
}
else if(strstr(line, "with CRLF line terminators"))
{
;
}
else if(strstr(line, "ASCII text"))
{
printf("%s\n", argv[i]);
}
pclose(fpin);
}
return 0;
}