Ho un file temp
con alcuni contenuti in minuscolo e maiuscolo.
Input
Contenuto del mio file temp
:
hi Jigar GANDHI jiga
Desidero convertire tutto superiore in inferiore .
Comando
Ho provato il seguente comando:
sed -e "s/[A-Z]/[a-z]/g" temp
ma ho ricevuto un output sbagliato.
Risultato
Lo voglio come:
hi jigar gandhi jiga
Cosa deve essere nella parte sostituto di argomenti per sed
?
Commenti
- Vedi anche Come convertire i file txt UTF-8 in tutto maiuscolo in bash?
Risposta
Se il tuo input contiene solo caratteri ASCII, potresti usare tr
come:
o (meno facile da ricordare e digitare IMO; ma non limitato alle lettere latine ASCII, sebbene in alcune implementazioni tra cui GNU tr
, ancora limitato ai caratteri a byte singolo, quindi nelle versioni locali UTF-8, ancora limitato alle lettere ASCII):
tr "[:upper:]" "[:lower:]" < input
se devi utilizzare sed
:
sed "s/.*/\L&/g" < input
(qui assumendo limplementazione GNU).
Con POSIX sed
, devi “specificare tutte le traslitterazioni e poi puoi scegliere quale lettere che desideri convertire:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
Con awk
:
awk "{print tolower($0)}" < input
Commenti
- Tieni presente che
\L
è unestensione GNU. -
\L
funziona bene per me finora. En luce il punto che stai cercando di creare estensione GNU - @JigarGandhi.
sed
è un comando Unix. Sistemi differenti hanno varianti differenti con comportamenti differenti e funzionalità d. Per fortuna, al giorno doggi, esiste ‘ uno standard a cui si conforma maggiormente, quindi puoi contare su un insieme minimo di funzionalità comuni a tutti.\L
non è tra questi ed è stato introdotto da GNUsed
(corrisponde allo stesso operatore nello standardex
/vi
) e generalmente non è disponibile in altre implementazioni. - Tieni presente che alcune
tr
implementazioni come GNUtr
don ‘ t funziona correttamente in locali multibyte (la maggior parte di questi sono oggigiorno, provaecho STÉPHANE | tr '[:upper:]' '[:lower:]'
per esempio). Sui sistemi GNU, potresti preferire la variantesed
oawk
‘ stolower()
. - Leggera correzione:
sed 's/.*/\L&/g' < input
. Il\1
riferimento alla sottostringa corrispondente ‘ non funzionerà a meno che non specifichi la sottostringa tra parentesi come fa wurtle nel suo. Tuttavia, ‘ è leggermente più pulito utilizzare&
per rappresentare lintera corrispondenza, come mostrato
Risposta
Utilizzando vim, è semplicissimo:
$ vim filename gg0guGZZ
Si apre il file gg
va alla prima riga, 0
, prima colonna. Con guG
, abbassa le maiuscole e le minuscole di tutti i caratteri fino alla fine del file. ZZ
salva ed esce.
Dovrebbe gestire quasi tutto ciò che gli lanci; “Ignorerà i numeri,” gestirà non ASCII.
Se vuoi fare il contrario, trasforma le lettere minuscole in maiuscole, scambia il u
fuori per un U
: gg0gUGZZ
e sei pronto.
Commenti
- Lol ” super semplice ”
- ovviamente non ‘ t scalare bene per molti file
- @CoreyGoldberg
vim file1 file2 fileetc
e poi qualcosa come:bufdo gg0guG:w<CR>
probabilmente funziona per un numero qualsiasi di file. Non lho testato però! - @TankorSmash che ancora ‘ t scala a un numero elevato di file
Risposta
Mi piace dd
per questo, me stesso.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… ottiene …
hi jigar ghandi jiga
Il LC_ALL=C
serve a proteggere qualsiasi multibyte in input, sebbene le maiuscole multibyte non verranno convertite. Lo stesso vale per (GNU) tr
: entrambe le app tendono a manipolare linput in qualsiasi locale non C. iconv
può essere combinato con entrambi per una soluzione completa.
Il 2>/dev/null
reindirizza scarta il rapporto di stato predefinito del dd
“e il relativo stderr. Senza di esso dd
seguirà il completamento di un lavoro come il precedente con informazioni di stampa come quanti byte sono stati elaborati e così via
Commenti
- Questa soluzione è molto più veloce di
tr
quando si gestiscono file di grandi dimensioni, grazie!
Risposta
Puoi anche utilizzare Perl 5:
perl -pe "$_=lc" temp
Lopzione -p
dice perl per eseguire lespressione specificata una volta per ogni riga di input, stampando il risultato, ovvero il valore finale di $_
. -e
indica che il programma sarà largomento successivo, al contrario di un file contenente lo script. lc
converte in minuscolo. Senza un argomento, funzionerà su $_
. E $_=
lo salva di nuovo in modo che venga stampato.
Una variazione sarebbe
perl -ne "print lc" temp
Usare -n
è come -p
tranne per il fatto che $_
non verrà stampato alla fine. Quindi, invece di salvare su quella variabile, includo unesplicita istruzione print.
Un vantaggio di Perl rispetto a sed è che non hai bisogno di alcuna estensione GNU. Ci sono progetti che devono essere compatibili con ambienti non GNU ma che hanno già una dipendenza da Perl. Rispetto a tr
, potrebbe essere che Perl lc
possa essere reso più facilmente compatibile con le impostazioni locali. Consulta la pagina man perllocale
per i dettagli.
Risposta
Devi acquisire il pattern corrispondente e quindi utilizzalo nella sostituzione con un modificatore:
sed "s/\([A-Z]\)/\L\1/g" temp
\(...\)
“cattura” il racchiudendo il testo corrispondente, la prima cattura va a \1
, la successiva a \2
, ecc. La numerazione è in base alle parentesi di apertura in caso di acquisizioni nidificate.
\L
converte il pattern acquisito in minuscolo, cè anche \U
per maiuscolo .
Commenti
- non è necessario farlo – lintero pattern è sempre catturato in
&
- Vero, ma poi avrei perso lopportunità di spiegare come catturare le corrispondenze 🙂
Risposta
Oltre alla risposta di MvG, potresti anche utilizzare Perl 6:
perl6 -pe .=lc temp
Qui $ _ è implicito e non hai bisogno delle virgolette singole per proteggerlo dallespansione da parte della shell ($ _ è uno speciale parametro Bash; vedere: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )