Como posso executar o dos2unix em um diretório inteiro? [fechadas]


Respostas:


591

find . -type f -print0 | xargs -0 dos2unix

Irá encontrar recursivamente todos os arquivos no diretório atual e solicitar o comando dos2unix desses arquivos


94
Quebraria se você tivesse espaços no nome do arquivo. find . -type f -print0 | xargs -0 dos2unixresolveria o problema que eu acho.
Noufal Ibrahim 13/08/2012

1
Eu dei como esse achado. -type f -exec dos2unix {} / home / venuk / Desktop / NEO_Src e deu o achado de erro: falta argumento para `-exec'
Vivek Gaur

1
Observe que a barra invertida que escapa do ponto-e-vírgula garante que os comandos dos2unix sejam separados por ponto-e-vírgula, para que eles não acabem juntos. Se você deseja executar um outro comando, depois, você vai precisar de outro ponto e vírgula, então\;; echo Hello
Josh

1
Tenha cuidado com este comando, porém, ele não verifica se o arquivo precisa da conversão; portanto, mesmo os arquivos binários serão "convertidos", corrompendo-os.
vguzmanp

2
@vguzmanp É verdade que a findinvocação não faz essa verificação (embora isso seja simples o suficiente para adicionar), mas o moderno dos2unixignora corretamente os arquivos binários.
Kyle Strand

68

Se for um diretório grande, considere executar com vários processadores:

find . -type f -print0 | xargs -0 -n 1 -P 4 dos2unix 

Isso passará 1 arquivo por vez e usará 4 processadores.


1
Este método tem a vantagem de continuar, mesmo que o dos2unix encontre algum problema! Algo como um método "--force". Obrigado por isso!
freeo

Uau - poupou-me muito tempo para resolver problemas ao tentar converter adições de código de desenvolvedores do Windows que tinham adicionado incorretamente o git à cama. Obrigado!!
The NetYeti

1
Iniciar um novo processo dos2unix para cada arquivo individual apresentará uma sobrecarga massivamente desnecessária. Eu bater que npor uma ordem de magnitude ou dois (dependendo de quantos arquivos que estamos falando aqui)
JonoCoetzee

25

Como fiquei satisfeito com o dos2unix, estendi meu próprio utilitário simples. Além de algumas vantagens em velocidade e previsibilidade, a sintaxe também é um pouco mais simples:

endlines unix *

E se você quiser que ele desça em subdiretórios (pulando diretórios ocultos e arquivos não textuais):

endlines unix -r .

endlinesestá disponível aqui https://github.com/mdolidon/endlines


1
Isto é perfeito! O mais próximo de uma linha que eu poderia chegar a isso é aqui: unix.stackexchange.com/a/365679/112190
phyatt

2
Como isso melhora dos2unix? Genuinamente curioso.
Walf

3
1 / Principalmente, existem toneladas de diferentes dos2unix, com recursos variados (alguns leem UTF32, por exemplo, enquanto outros não; as linhas finais não). Há apenas um endlines, cujos recursos são bem conhecidos. 2 / liberal na entrada, nem todos dos2unixsão. 3 / exploração eficiente da árvore de arquivos, projetada para ser rápida e prática em dezenas de milhares de arquivos. 4 / sai da caixa no OSX - o que é menos importante agora que o pacote Brew existe.
Mathias Dolidon

1
No meu caso, é exatamente o que eu precisava, muito obrigado. Os recursos bem-vindos são a maneira fácil de processar uma árvore de diretórios e o rápido tempo de execução.
AlSavi 10/03

17

Provavelmente, é melhor pular arquivos e pastas ocultos, como .git.Então, em vez de usar find, se sua bashversão é recente o suficiente ou se você estiver usando zsh, basta:

dos2unix **

Observe que, para o Bash, isso exigirá:

shopt -s globstar

.... mas esse é um recurso útil o suficiente para você honestamente colocá-lo de .bashrcqualquer maneira.

Se você não quiser pular arquivos e pastas ocultos, mas ainda não quiser mexer find(e eu não o culpo), você pode fornecer um segundo argumento de recursive-glob para corresponder apenas às entradas ocultas:

dos2unix ** **/.*

Observe que, em ambos os casos, o glob se expandirá para incluir diretórios; portanto, você verá o seguinte aviso (possivelmente várias vezes): Skipping <dir>, not a regular file.


1
Isso não funcionou para mim. A sintaxe da globstar funciona para dos2unix? Eu usei a globstar em outro lugar com sucesso, mas não consegui fazer isso funcionar. Estou usando o Bash 4.3.11 (1)
NS du Toit

As conchas no estilo @NSduToit * NIX não permitem que os executáveis ​​alterem o comportamento da expansão de argumentos, porque (ao contrário do Windows) a expansão de argumentos é executada antes que o executável receba os argumentos. Portanto, a única coisa em que consigo pensar é que você tem algum tipo de dos2unixalias que afeta a maneira como os argumentos são expandidos. Qual é a saída do type dos2unixseu sistema?
Kyle Strand

1
@NSduToit Há alguma confusão aqui. Minha resposta afirma explicitamente que o objetivo de usar, em **vez de, findé "pular arquivos e pastas ocultos, como .git". dos2unixnunca vê os arquivos ocultos, porque **não se expande para mostrá-los. Se você deseja executar automaticamente dos2unixem arquivos e pastas ocultos, pode usar findou dos2unix ** **/.*O **/.*expandirá apenas os arquivos e pastas ocultos, incluindo .(o diretório raiz), ..(o diretório pai) e quaisquer outras entradas ocultas na pasta atual.
Kyle Strand

1
(Observe que dos2unixsimplesmente é impresso Skipping <dir>, not a regular file.quando executado em um diretório, portanto, executando ..e .é seguro.) Além disso, combinar lscom um globo não é uma boa maneira de verificar como o globo é expandido; use echovez: echo **imprime os argumentos que dos2unixrecebe de dos2unix **.
Kyle Strand

1
Obrigado! Faz sentido! Ok, eu tinha uma ideia totalmente errada sobre o que estava **implícito, e o uso echodeixa claro.
NS du Toit

7

Um caso de uso comum parece ser padronizar as terminações de linha para todos os arquivos confirmados em um repositório Git :

git ls-files | xargs dos2unix

Tenha em mente que certos arquivos (por exemplo *.sln, *.bat) etc são unicamente utilizado em sistemas operacionais Windows e deve manter a CRLFterminar:

git ls-files '*.sln' '*.bat' | xargs unix2dos

Se necessário, use .gitattributes


6

Para qualquer usuário do Solaris (estou usando a 5.10, também pode se aplicar a versões mais recentes, bem como a outros sistemas unix):

O dos2unix não substitui o arquivo por padrão, ele apenas imprime a versão atualizada no stdout; portanto, você terá que especificar a origem e o destino, ou seja, o mesmo nome duas vezes:

find . -type f -exec dos2unix {} {} \;

2
for FILE in /var/www/html/files/*
do
 /usr/bin/dos2unix FILE
done

1
Bem-vindo ao Stack Overflow. Embora sua solução seja válida, seria ótimo se você pudesse adicionar alguma explicação. Você também pode consultar outras respostas para justificar sua resposta. Por favor, dê uma olhada em Como responder para obter mais informações.
kvantour

2

Eu tive o mesmo problema e, graças aos posts aqui, eu o resolvi. Eu sabia que tinha cerca de cem arquivos e precisava executá-lo apenas para arquivos * .js. find . -type f -name '*.js' -print0 | xargs -0 dos2unix

Obrigado a todos por sua ajuda.


0

Eu acho que a maneira mais simples é:

dos2unix $(find . -type f)

0

Eu pesquisei isso como um milhão de vezes, então minha solução é apenas colocar essa função bash no seu ambiente.

.bashrcou .profileou o que quer

dos2unixd() {
  find $1 -type f -print0 | xargs -0 dos2unix
}

Uso

$ dos2unixd ./somepath

Dessa forma, você ainda tem o comando original dos2unixe é fácil lembrar deste dos2unixd.


-1

Se não houver subdiretório, você também pode

ls | xargs -I {} dos2unix "{}"

4
Se não houver subdiretórios, dos2unix *é mais simples e, na verdade, será mais robusto que isso. (Geralmente não é recomendado para canalizar a saída de ls, porque é uma ferramenta de formatação e *é mais confiável para uso programático.)
Kyle Strand

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.