Converter o conteúdo do arquivo em minúsculas

85

Eu tenho um temparquivo com alguns conteúdos em minúsculas e maiúsculas.

Entrada

Conteúdo do meu temparquivo:

hi
Jigar
GANDHI
jiga

Eu quero converter tudo superior para inferior .

Comando

Eu tentei o seguinte comando:

sed -e "s/[A-Z]/[a-z]/g" temp

mas tem saída errada.

Resultado

Quero como:

hi
jigar
gandhi
jiga

O que precisa estar na parte substituta do argumento sed?

JigarGandhi
fonte

Respostas:

122

Se sua entrada contiver apenas caracteres ASCII, você poderá usar trcomo:

tr A-Z a-z < input 

ou (menos fácil de lembrar e digitar IMO; mas não limitado a letras latinas ASCII, embora em algumas implementações incluindo GNU tr, ainda limitado a caracteres de byte único, portanto nos locais UTF-8, ainda limitado a letras ASCII):

tr '[:upper:]' '[:lower:]' < input

se você precisar usar sed:

sed 's/.*/\L&/g' < input

(assumindo aqui a implementação GNU).

Com o POSIX sed, você precisa especificar todas as transliterações e escolher as letras que deseja converter:

sed 'y/AǼBCΓDEFGH.../aǽbcγdefgh.../' < input

Com awk:

awk '{print tolower($0)}' < input
Anthon
fonte
3
Por favor, note que \Lé uma extensão GNU.
Anthon
\Lfunciona bem para mim até agora. En iluminar o ponto que você está tentando fazer extensão GNU
JigarGandhi
2
@JigarGandhi. sedé um comando Unix. Sistemas diferentes têm variantes diferentes com comportamento e funcionalidade diferentes. Felizmente, hoje em dia, existe um padrão mais adequado para que você possa contar com um conjunto mínimo de recursos comuns a todos. \Lnão está entre eles e foi introduzido pelo GNU sed(corresponde ao mesmo operador no padrão ex/ vi) e geralmente não está disponível em outras implementações.
Stéphane Chazelas
9
Observe que algumas trimplementações como o GNU trnão funcionam corretamente em locais de vários bytes (a maioria deles atualmente, tente echo STÉPHANE | tr '[:upper:]' '[:lower:]'por exemplo). Nos sistemas GNU, você pode preferir a sedvariante ou awk's tolower().
Stéphane Chazelas
5
Correção ligeira: sed 's/.*/\L&/g' < input. A \1referência à substring correspondente não funcionará, a menos que você especifique a substring entre parênteses, como o wurtle faz no dele. No entanto, é um pouco mais limpo de usar &para representar a partida inteira, como mostrado
Edward Brown
30

Usando o vim, é super simples:

$ vim filename
gg0guGZZ

Abre o arquivo, ggvai para a primeira linha 0, primeira coluna. Com guG, reduz o caso de todos os caracteres até a parte inferior do arquivo. ZZsalva e sai.

Ele deve lidar com praticamente qualquer coisa que você jogar nele; ignorará números, tratará não ASCII.

Se você quiser fazer o oposto, transforme as letras minúsculas em maiúsculas, troque a usaída por a U: gg0gUGZZe pronto.

TankorSmash
fonte
14
Lol "super simples"
blambert
Isto, obviamente, não escala bem para muitos arquivos
Corey Goldberg
minha resposta mais favorita até agora !!!!
Mona Jalal
11
@CoreyGoldberg vim file1 file2 fileetce, em seguida, algo como :bufdo gg0guG:w<CR>seria provavelmente funcionar para qualquer número de arquivos. Ainda não testei isso!
precisa saber é o seguinte
@TankorSmash que ainda não escala a um grande número de arquivos
Corey Goldberg
17

Eu gosto dddisso também.

<<\IN LC_ALL=C 2<>/dev/null \
dd conv=lcase
hi
Jigar 
GANDHI
jiga
IN

... fica ...

hi
jigar
ghandi
jiga

O LC_ALL=Cobjetivo é proteger todos os multibytes na entrada - embora as letras maiúsculas e minúsculas não sejam convertidas. O mesmo vale para (GNU) tr - os dois aplicativos são propensos a entrada de dados em qualquer local não C. iconvpode ser combinado com qualquer um para uma solução abrangente.

O 2>/dev/nullredirecionamento descarta ddo relatório de status padrão - e seu stderr. Sem isso dd, seguiria a conclusão de um trabalho como o acima, com informações de impressão, como quantos bytes foram processados ​​e etc.

mikeserv
fonte
Esta solução é muito mais rápida do que trquando se lida com arquivos grandes, obrigado!
WhiteWinterWolf
13

Você também pode usar o Perl 5:

perl -pe '$_=lc' temp

A opção -pdiz ao perl para executar a expressão especificada uma vez para cada linha de entrada, imprimindo o resultado, ou seja, o valor final de $_. -eindica que o programa será o próximo argumento, em oposição a um arquivo que contém o script. lcconverte para minúsculas. Sem argumento, ele funcionará $_. E $_=salva isso novamente para que seja impresso.

Uma variação disso seria

perl -ne 'print lc' temp

Usar -né como, -pexceto que $_não será impresso no final. Então, em vez de salvar nessa variável, estou incluindo uma declaração de impressão explícita.

Um benefício do Perl, em contraste com o sed, é que você não precisa de nenhuma extensão GNU. Existem projetos que precisam ser compatíveis com ambientes não-GNU, mas que também já possuem Perl como dependência. Comparado com tr, pode ser que o Perl lcpossa ser mais facilmente reconhecido pelo local. Veja a perllocalepágina de manual para detalhes.

MvG
fonte
9

Você precisa capturar o padrão correspondente e usá-lo na substituição com um modificador:

sed 's/\([A-Z]\)/\L\1/g' temp

As \(...\)"capturas" do texto correspondente em anexo, a primeira captura \1, a próxima a \2etc. A numeração é de acordo com colchetes de abertura no caso de capturas aninhadas.

O \Lconverte o padrão capturado em minúsculas, e também \Uem maiúsculas.

Wurtel
fonte
3
você não precisa fazer isso - todo o padrão é sempre pego em&
mikeserv
É verdade, mas então eu teria perdido a oportunidade de explicar a captura de jogos :-)
wurtel