Eu tenho um arquivo temp
com alguns conteúdos em minúsculas e maiúsculas.
Entrada
Conteúdo do meu temp
arquivo:
hi Jigar GANDHI jiga
Quero converter todos os superiores para inferiores .
Comando
Tentei o seguinte comando:
sed -e "s/[A-Z]/[a-z]/g" temp
mas obtive a saída errada.
Saída
Eu quero isso como:
hi jigar gandhi jiga
O que precisa estar na parte substituta de argumento para sed
?
Comentários
- Veja também Como converter arquivos txt UTF-8 em maiúsculas em bash?
Resposta
Se sua entrada contiver apenas caracteres ASCII, você pode usar tr
como:
ou (menos fácil de lembrar e digite 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, em localidades UTF-8, ainda limitado a letras ASCII):
tr "[:upper:]" "[:lower:]" < input
se você tiver que usar sed
:
sed "s/.*/\L&/g" < input
(aqui assumindo a implementação GNU).
Com POSIX sed
, você “d precisa especificar todas as transliterações e então você pode escolher quais letras que você deseja converter:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
Com awk
:
awk "{print tolower($0)}" < input
Comentários
- Observe que
\L
é uma extensão GNU. -
\L
funciona bem para mim até agora. Reveja o que você está tentando fazer com a extensão GNU - @JigarGandhi.
sed
é um comando Unix. Diferentes sistemas têm diferentes variantes com diferentes comportamentos e funcionalidade d. Felizmente, hoje em dia, existe ‘ s um padrão que mais está em conformidade, então você pode contar com um conjunto mínimo de recursos comuns a todos.\L
não está entre eles e foi introduzido pelo GNUsed
(corresponde ao mesmo operador noex
/vi
) e geralmente não está disponível em outras implementações. - Observe que algumas
tr
implementações como GNUtr
não ‘ não funcione corretamente em localidades multibyte (a maioria delas atualmente, tenteecho STÉPHANE | tr '[:upper:]' '[:lower:]'
por exemplo). Em sistemas GNU, você pode preferir ased
variante ouawk
‘ stolower()
. - Ligeira correção:
sed 's/.*/\L&/g' < input
. A\1
referência à substring correspondida ‘ não funcionará, a menos que você especifique a substring com parênteses como o wurtle faz no seu. No entanto, é ‘ um pouco mais limpo usar&
para representar toda a correspondência, conforme mostrado
Resposta
Usando o vim, é super simples:
$ vim filename gg0guGZZ
Abre o arquivo, gg
vai para a primeira linha, 0
, primeira coluna. Com guG
, diminui a caixa de todos os caracteres até o final do arquivo. ZZ
salva e sai.
Ele deve lidar com quase tudo que você jogar nele; “Vou ignorar números,” não vai lidar com ASCII.
Se você quiser fazer o oposto, transforme as letras minúsculas em maiúsculas, troque o u
para um U
: gg0gUGZZ
e você “está pronto.
Comentários
- Lol ” super simples ”
- isso obviamente não ‘ t escala bem para muitos arquivos
- @CoreyGoldberg
vim file1 file2 fileetc
e algo como:bufdo gg0guG:w<CR>
provavelmente provavelmente funciona para qualquer número de arquivos. Ainda não testei isso! - @TankorSmash que ainda não ‘ se escala para um número grande de arquivos
Resposta
Eu mesmo gosto de dd
para isso.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… obtém …
hi jigar ghandi jiga
O LC_ALL=C
é para proteger quaisquer multibytes na entrada – embora quaisquer maiúsculas multibyte não sejam convertidas. O mesmo é verdadeiro para (GNU) tr
– ambos os aplicativos são propensos a distorção de entrada em qualquer localidade não C. iconv
pode ser combinado com qualquer um para uma solução abrangente.
O 2>/dev/null
redirecionamento descarta o dd
“relatório de status padrão – e seu stderr. Sem ele dd
seguiria a conclusão de um trabalho como o acima c / imprimindo informações como quantos bytes foram processados e etc.
Comentários
- Esta solução é muito mais rápida do que
tr
ao lidar com arquivos grandes, obrigado!
Resposta
Você também pode usar Perl 5:
perl -pe "$_=lc" temp
A opção -p
diz perl para executar a expressão especificada uma vez para cada linha de entrada, imprimindo o resultado, ou seja, o valor final de $_
. -e
indica que o programa será o próximo argumento, ao contrário de um arquivo que contém o script. lc
é convertido em minúsculas. Sem um argumento, ele operará em $_
. E $_=
salva isso novamente para que seja impresso.
Uma variação disso seria
perl -ne "print lc" temp
Usando -n
é como -p
exceto que $_
não “será impresso no final. Portanto, em vez de salvar nessa variável, estou incluindo uma instrução print explícita.
Um benefício do Perl em comparação com o sed é que você não precisa de nenhuma extensão GNU. Existem projetos que devem ser compatíveis com ambientes não GNU, mas que também já possuem uma dependência do Perl. Comparado com tr
, pode ser que o Perl lc
possa reconhecer a localidade mais facilmente. Consulte a perllocale
página do manual para obter detalhes.
Resposta
Você precisa capturar o padrão correspondente e, em seguida, use-o na substituição por um modificador:
sed "s/\([A-Z]\)/\L\1/g" temp
O \(...\)
“captura” o delimitando o texto correspondente, a primeira captura vai para \1
, a próxima para \2
, etc. A numeração é de acordo com os colchetes de abertura no caso de capturas aninhadas.
O \L
converte o padrão capturado em minúsculas, também há \U
para maiúsculas .
Comentários
- você não precisa fazer isso – todo o padrão é sempre capturado em
&
- Verdadeiro, mas eu teria perdido a oportunidade de explicar a captura de correspondências 🙂
Resposta
Além da resposta de MvG”, você também pode usar Perl 6:
perl6 -pe .=lc temp
Aqui $ _ está implícito e você não precisa das aspas simples para protegê-lo da expansão pelo shell ($ _ sendo um parâmetro especial do Bash; consulte: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )