grep para encontrar arquivos que contêm ^ M (retorno de carro do Windows)

72

Eu uso Linux. Há um ^ M irritante (retorno de cartografia do Windows) em algum lugar escondido em milhares de arquivos de configuração, e preciso encontrá-lo, porque isso faz com que o servidor falhe.

Como encontro ^ M em uma hierarquia de diretórios cheia de arquivos de configuração?

Acho que não consigo inserir ^ M na linha de comando do bash. Mas eu o tenho em um arquivo de texto que chamei m.txt

Nicolas Raoul
fonte
Relacionado: Remova o retorno de carro no Unix .
40XUserNotFound
janelas seria ^ M ^ J
barlop 20/09/2015
3
"Não consigo inserir ^ M na linha de comando do bash". Sim você pode. Tente control-V Control-M
Hennes

Respostas:

91
grep -r $'\r' *

Use -rpara pesquisa recursiva e $''para escape no estilo c no Bash.

Além disso, se você tem certeza de que é um arquivo de texto, deve ser seguro executar

tr -d $'\r' < filename

para remover tudo \rem um arquivo.

Se você usa o GNU sed, -ipode executar edições no local, para que não precise escrever de volta:

sed $'s/\r//' -i filename
livibetter
fonte
10
@ Nicolas: Você pode inserir um ^ M na linha de comando pressionando ^ V ^ M, mas é melhor usar $'\r'.
Dennis Williamson
Ótimo, funciona! Agradeço também o truque ^ V ^ M :-) #
913 Nicolas Raoul
5
Sob Cygwin, -U é necessário para fazer isso funcionar. E -n irá dizer-lhe o número da linha: grep -r -U -n -e $ '\ r'
Rainer Blome
4
Adicione -l ao comando grep para visualizar apenas os nomes dos arquivos. Caso contrário, você pode ser bombardeado com linhas correspondentes.
Brendan Byrd
11
@ uprego não tenho certeza se você os entende agora, mas para a pesquisa de outras pessoas, $'leia o primeiro hit na página de manual bash(1), basicamente, você pode vê-lo como se estivesse escrevendo uma string literal C. Quanto command < filenameao uso de <ou >é chamado de redirecionamento , é a primeira vez que vejo alguém chamar isso de maior expressão . Pesquisar REDIRECTIONem bash(1).
livibetter 23/09/15
12

Quando tentei, percebi que estava meio que funcionando, mas as linhas estavam imprimindo em branco. Adicione na opção:

--color=never

Se você receber esse problema, acho que são os caracteres de escape do realce de cores que interferem no \rpersonagem.

Judson Wilson
fonte
2

Se o servidor não tiver um shell bash, uma alternativa é usar a -fopção grep, em combinação com um arquivo preparado contendo \r.

Para criar o arquivo:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

Para realmente fazer a pesquisa

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

ou você pode ser um pouco preguiçoso e apenas digitar *,

$ grep -f /tmp/cr *

A opção ativada é usada para especificar um arquivo que contém padrões para corresponder, um por linha. Nesse caso, há apenas um padrão.-f filenamegrep

Kiwi Nick
fonte
2

Se eu entendi sua pergunta corretamente, o que você realmente deseja é normalizar todas as terminações de linhas no \x0apadrão Unix LF ( ). Isso não é o mesmo que remover cegos CRs ( \x0d).

Se você tiver alguns arquivos do Mac que usam apenas CR para novas linhas, você os destruirá. (Sim, os Macs devem usar o LF há quase 20 anos, mas ainda existem (em 2019) muitos aplicativos para Mac que usam apenas CR).

Você pode usar o \R escape de quebra de linha do Perl para substituir qualquer tipo de nova linha \n.

perl -i.bak -pe 's/\R/\n/g' $your_file

Isso substituiria no local qualquer tipo de quebra de linha por \nin $your_file, mantendo um backup do arquivo original ${your_file}.bak.

mivk
fonte
1

Para usar grep em caracteres de fim de linha, acho que você precisa informar ao grep que o arquivo é binário.

-l (letra L) é para imprimir apenas o nome do arquivo

-P é para perl regexp (então \ x0d é transformado em \ r ou ^ M)

grep -l --binary -P '\x0d' *
Vouze
fonte
0

Se você estiver em um Mac e usar o homebrew , poderá:

brew install tofrodos
fromdos file.txt

remover todos os retornos de carro do Windows de file.txt

Para voltar aos retornos de carro do Windows,

todos file.txt
Kortina
fonte
Para pesquisar em uma pasta e limpar todos os arquivos provenientes do DOS, execute este comando: find. -type f -name "* .java" | xargs fromdos
Taiko
0

No estilo de expressão regular, várias novas linhas:

Windows (CR LF)
\r\n

Unix (LF)
\n

Como a \r\nsequência é bastante única, acho que você deve procurar dessa maneira?

Para piorar as coisas, os Macs costumavam ter apenas '\ r' no lugar da nova linha. Não posso verificar isso, mas acho que as gerações do MacOSX não fazem mais isso.

Macs mais antigos (CR)
\r

Jeff Atwood
fonte
No diretório que contém m.txt, grep "\r\n" *não dá resultado. Nenhum resultado para egrep -e "\r\n" *norgrep -E "\r\n" *
Nicolas Raoul
@ nicolas ah, eu entendi errado .. você quis dizer CR apenas o \rmeu mal. A janela de nova linha completa de fato \r\nou CRLF
Jeff Atwood
0

Seguindo as respostas anteriores, o método 'tr' é bom:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; depois ecoar "DOS"; else echo "UNIX"; fi

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; depois ecoar "DOS"; else echo "UNIX"; fi

DOS

Malcolm Boekhoff
fonte