Como detectar arquivos no formato git bash

4

O Git Bash é um bom bash shell que você obtém no Windows como parte da instalação do Git. Ele vem com outras ferramentas típicas do UNIX, como grep, sed, awk, perl. Não tem o comando file.

Neste shell, quero detectar arquivos que tenham finais de linha no estilo DOS. Eu pensei que esse comando funcionaria, mas não funciona:

grep -l ^M$ *

Ele não funciona, até mesmo arquivos que não possuem finais de linha CR coincidem. Por exemplo, se eu criar 2 arquivos de amostra hello.unix e hello.dos , posso confirmar com wc que hello.unix tem 6 caracteres e hello.dos tem 7 caracteres devido ao CR extra, mas ambos os arquivos correspondem a grep . Isso é:

$ 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

Isso é um bug na implementação de grep no Git Bash? Existe outra maneira de encontrar todos os arquivos com finais de linha no estilo DOS?

    
por janos 11.10.2012 / 11:11

5 respostas

1

@sch me levou a essa solução:

sed -bne '/\r$/ {p;q}' < /path/to/file | grep -q .

Isso sai com TRUE se o arquivo tiver qualquer linha que termine com CR. Para colocar isso em prática:

find /path/to/ -type f -exec sh -c 'sed -bne "/\r$/ {p;q}" < "$1" | grep -q .' sh {} \; -print

E eu acho que sei porque grep -l ^M hello.* não funciona neste shell: parece que no Git Bash ^M caracteres são removidos de todos os argumentos da linha de comando, então grep nunca recebe o caractere e, portanto, todos os arquivos correspondem. Esse comportamento não é apenas na linha de comando, mas também em scripts de shell.

Portanto, a chave é expressar o caractere ^M com outros símbolos, como \r , em vez de literalmente.

    
por 12.10.2012 / 10:42
4

EDIT: Tolo eu. Claro que ^ M é CR; e seu comando deve funcionar (funciona no meu sistema). No entanto, você precisa digitar Ctrl-V Ctrl-M para obter o literal '\ r' / CR (e não dois caracteres, ^ e M ).

Alternativas:

Faça isso:

find dir -type f -print0 | xargs -0 grep -l 'printf '\r\n''

Ou isto:

find dir -type f -print0 | xargs -0 grep -lP '\r\n'

Você também pode usar o utilitário de arquivos (não tenho certeza se vem com o GIT bash):

find dir -type f -print0 | xargs -0 file | grep CRLF
    
por 11.10.2012 / 11:34
2

Eu não sei sobre o git bash, mas talvez

if [ "$(tr -cd '\r' < file | wc -c)" -gt 0 ]; then
  echo there are CR characters in there
fi

funcionaria. A idéia é não usar utilitários text que possam tratar os caracteres CR e LF especialmente.

Se isso não funcionar, talvez

if od -An -tx1 < file | grep -q 0d; then
  echo there are CR characters in there
fi

Para encontrar:

find . -type f -exec sh -c 'od -An -tx1 < "$1" | grep -q 0d' sh {} \; -print
    
por 11.10.2012 / 23:56
0

Você pode resolvê-lo usando o Python:

import string
import fileinput

for line in fileinput.input():
    if (string.find(line,"\r")!=-1):
        print fileinput.filename()
        fileinput.nextfile()

Esse pequeno arquivo python se comportaria exatamente como você esperaria do grep (obtenha uma lista de nomes de arquivos e imprima os nomes com CR neles).

    
por 11.10.2012 / 21:49
0

Use o comando file no Linux / Ubuntu. Se o arquivo estiver no formato DOS, a saída incluirá as palavras "com terminadores de linha CRLF". Se o arquivo estiver no formato UNIX, nenhuma dessas palavras estará na saída. No exemplo abaixo, del.txt está no formato DOS e del está no formato 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
    
por 23.07.2015 / 00:38