Converti il ​​contenuto del file in minuscolo


85

Ho un tempfile con alcuni contenuti in minuscolo e maiuscolo.

Ingresso

Contenuto del mio tempfile:

hi
Jigar
GANDHI
jiga

Voglio convertire tutto in alto in basso .

Comando

Ho provato il seguente comando:

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

ma ho un output sbagliato.

Produzione

Lo voglio come:

hi
jigar
gandhi
jiga

Cosa deve essere nella parte sostitutiva dell'argomento sed?


Risposte:


122

Se il tuo input contiene solo caratteri ASCII, puoi usare trcome:

tr A-Z a-z < input 

o (meno facile da ricordare e digitare IMO; ma non limitato a lettere latine ASCII, sebbene in alcune implementazioni tra cui GNU tr, ancora limitato a caratteri a byte singolo, quindi in locali UTF-8, ancora limitato a lettere ASCII):

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

se devi usare sed:

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

(qui assumendo l'implementazione GNU).

Con POSIX sed, dovresti specificare tutte le traslitterazioni e quindi puoi scegliere quali lettere vuoi convertire:

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

Con awk:

awk '{print tolower($0)}' < input

3
Si noti che \Lè un'estensione GNU.
Anthon,

\Lfunziona bene per me finora. Alla luce del punto che stai cercando di fare l' estensione GNU
JigarGandhi il

2
@JigarGandhi. sedè un comando Unix. Sistemi diversi hanno varianti diverse con comportamento e funzionalità diverse. Per fortuna, al giorno d'oggi, esiste uno standard a cui è più conforme in modo da poter contare su un set minimo di funzionalità comuni a tutti. \Lnon è tra questi ed è stato introdotto da GNU sed(corrisponde allo stesso operatore in standard ex/ vi) e generalmente non è disponibile in altre implementazioni.
Stéphane Chazelas,

9
Nota che alcune trimplementazioni come GNU trnon funzionano correttamente nelle localizzazioni multi-byte (la maggior parte di esse è al giorno d'oggi, prova echo STÉPHANE | tr '[:upper:]' '[:lower:]'ad esempio). Sui sistemi GNU, potresti preferire la sedvariante o awk's tolower().
Stéphane Chazelas,

5
Leggera correzione: sed 's/.*/\L&/g' < input. Il \1riferimento alla sottostringa abbinata non funzionerà a meno che non specifichi la sottostringa tra parentesi come fa Wurtle nella sua. Tuttavia, è leggermente più pulito da usare &per rappresentare l'intera partita, come mostrato
Edward Brown,

30

Usando vim, è super semplice:

$ vim filename
gg0guGZZ

Apre il file, ggpassa alla prima riga 0, prima colonna. Con guG, abbassa il caso di tutti i caratteri fino alla fine del file. ZZsalva ed esce.

Dovrebbe gestire praticamente qualsiasi cosa tu gli lanci; ignorerà i numeri, gestirà non ASCII.

Se vuoi fare il contrario, trasforma le lettere maiuscole in maiuscole, scambia le lettere ucon un U: gg0gUGZZe sei pronto.


14
Lol "super semplice"
blambert,

questo ovviamente non si adatta bene a molti file
Corey Goldberg,

la mia risposta più preferita finora !!!!
Mona Jalal,

1
@CoreyGoldberg vim file1 file2 fileetce poi qualcosa di simile :bufdo gg0guG:w<CR>sarebbe probabilmente funzionare per qualsiasi numero di file. Non l'ho provato però!
TankorSmash

@TankorSmash che ancora non si adatta a un gran numero di file
Corey Goldberg

17

Mi piace ddper questo, me stesso.

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

...prende...

hi
jigar
ghandi
jiga

Lo scopo LC_ALL=Cè proteggere qualsiasi multibyte in input, anche se le maiuscole multibyte non verranno convertite. Lo stesso vale per (GNU) tr : entrambe le app sono inclini a manipolare l'input in qualsiasi locale non-C. iconvpuò essere combinato con entrambi per una soluzione completa.

Il 2>/dev/nullreindirizzamento elimina ddil rapporto sullo stato predefinito e il suo standard. Senza di essa ddseguirebbe il completamento di un lavoro come quello sopra con informazioni di stampa come quanti byte sono stati elaborati ed ecc.


Questa soluzione è molto più veloce rispetto tralla gestione di file di grandi dimensioni, grazie!
WhiteWinterWolf

13

Puoi anche usare Perl 5:

perl -pe '$_=lc' temp

L'opzione -pdice a perl di eseguire l'espressione specificata una volta per ogni riga di input, stampando il risultato, ovvero il valore finale di $_. -eindica che il programma sarà l'argomento successivo, a differenza di un file contenente lo script. lcconverte in minuscolo. Senza discussione, funzionerà $_. E lo $_=salva di nuovo in modo che venga stampato.

Una variazione di ciò sarebbe

perl -ne 'print lc' temp

L'uso -nè come -ptranne che $_non verrà stampato alla fine. Quindi, invece di salvare su quella variabile, includo un'istruzione esplicita di stampa.

Un vantaggio di Perl rispetto a sed è che non hai bisogno di alcuna estensione GNU. Esistono progetti che devono essere compatibili con ambienti non GNU ma che hanno già una dipendenza Perl asa. In confronto tr, è possibile che Perl lcpossa essere reso più facilmente consapevole delle impostazioni locali. Vedi la perllocalepagina man per i dettagli.


9

È necessario acquisire il modello corrispondente e quindi utilizzarlo nella sostituzione con un modificatore:

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

Il \(...\)"cattura" il testo abbinato che racchiude, la prima acquisizione va a \1, il successivo \2, ecc. La numerazione è in base alle parentesi aperte in caso di acquisizioni nidificate.

La \Lconverte il modello catturato a minuscolo, c'è anche \Uper il caso superiore.


3
non è necessario farlo - l'intero schema viene sempre catturato&
mikeserv il

È vero, ma avrei perso l'occasione di spiegare le partite catturate :-)
wurtel

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.