Konvertera filinnehåll till gemener

Jag har temp -fil med lite gemener och gemener.

Ingång

Innehåll i min temp -fil:

 hi Jigar GANDHI jiga  

Jag vill konvertera alla övre till nedre .

Kommando

Jag försökte följande kommando:

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

men fick fel utdata.

Output

Jag vill ha det som:

hi jigar gandhi jiga 

Vad som måste vara i ersättare delen av argument för sed?

Kommentarer

Svar

Om din inmatning bara innehåller ASCII-tecken kan du använda tr som:

eller (mindre lätt att komma ihåg och skriva IMO; men inte begränsat till ASCII-latinska bokstäver, men i vissa implementeringar inklusive GNU tr, fortfarande begränsad till enbyte-tecken, så i UTF-8-lokaler, fortfarande begränsad till ASCII-bokstäver): / p>

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

om du måste använda sed:

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

(här antar vi GNU-implementeringen).

Med POSIX sed behöver du ange alla translitterationer och sedan kan du välja vilken bokstäver du vill konvertera:

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

Med awk:

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

Kommentarer

  • Observera att \L är ett GNU-tillägg.
  • \L fungerar hittills bra för mig. Tänd punkten som du försöker göra GNU-tillägg
  • @JigarGandhi. sed är ett Unix-kommando. Olika system har olika varianter med olika beteende och d-funktionalitet. Tack och lov finns det numera ’ en standard som passar bäst så att du kan räkna med en minsta uppsättning funktioner som är gemensamma för alla. \L är inte bland dem och introducerades av GNU sed (matchar samma operatör i standard ex / vi) och är vanligtvis inte tillgängligt i andra implementeringar.
  • Observera att vissa tr -implementeringar som GNU tr don ’ t fungerar ordentligt i flera byte-platser (de flesta är nuförtiden, prova echo STÉPHANE | tr '[:upper:]' '[:lower:]' till exempel). På GNU-system föredrar du kanske sed -varianten eller awk ’ s tolower().
  • Lätt korrigering: sed 's/.*/\L&/g' < input. \1 referensen till matchad substring vann ’ t såvida du inte anger substringen med parentes som wurtle gör i hans. Det är dock ’ lite renare att använda & för att representera hela matchningen, som visas

Svar

Med vim är det super enkelt:

$ vim filename gg0guGZZ 

Öppnar filen gg går till första raden, 0, första kolumnen. Med guG , sänker bokstäverna för alla tecken tills botten av filen. ZZ sparar och avslutas.

Den ska hantera nästan vad som helst du kastar åt den; den ”kommer att ignorera siffror, det” kommer att hantera icke ASCII.

Om du vill göra det motsatta, vänd de små bokstäverna till versaler, byt u ute efter en U: gg0gUGZZ och du är inställd.

Kommentarer

  • Lol ” superenkelt ”
  • detta gör självklart inte ’ t skalar bra för många filer
  • @CoreyGoldberg vim file1 file2 fileetc och då skulle något som :bufdo gg0guG:w<CR> troligen / i> arbeta för valfritt antal filer. Har dock inte testat det!
  • @TankorSmash som fortfarande inte ’ t skalas till ett stort antal filer

Svar

Jag gillar dd för detta själv.

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

… får …

hi jigar ghandi jiga 

LC_ALL=C är för att skydda eventuella multibytes i inmatningen – även om alla multibyte-versaler inte kommer att konverteras. Detsamma gäller för (GNU) tr – båda apparna är benägna att mata in i alla länder som inte är C. iconv kan kombineras med antingen för en heltäckande lösning.

2>/dev/null omdirigerar dd ”standardstatusrapport – och dess stderr. Utan den dd skulle följa slutförandet av ett jobb som ovan med utskriftsinformation som hur många byte som bearbetades osv.

Kommentarer

  • Denna lösning är mycket snabbare än tr när du hanterar stora filer tack!

Svar

Du kan också använda Perl 5:

perl -pe "$_=lc" temp 

Alternativet -p berättar perl för att köra det angivna uttrycket en gång för varje inmatningsrad och skriva ut resultatet, dvs. det slutliga värdet av $_. -e indikerar att programmet blir nästa argument, till skillnad från en fil som innehåller skriptet. lc konverterar till gemener. Utan argument fungerar det på $_. Och $_= sparar det igen så att det skrivs ut.

En variant av det skulle vara

perl -ne "print lc" temp 

Använd -n är som -p förutom att $_ inte kommer att skrivas ut till slut. Så istället för att spara till den variabeln inkluderar jag ett uttryckligt utskriftsuttalande.

En fördel med Perl till skillnad från sed är att du inte behöver några GNU-tillägg. Det finns projekt som måste vara kompatibla med miljöer som inte är GNU men som också redan har Perl a s a dependency. Jämfört med tr kan det vara så att Perl lc lättare kan göras lokalmedveten. Se perllocale mansidan för mer information.

Svar

Du måste fånga det matchade mönstret och använd det i stället för en modifierare:

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

\(...\) ”fångar” omsluter matchad text, den första fångsten går till \1, nästa till \2 osv. Numreringen är enligt öppningsfästen i händelse av kapslade fångster.

\L konverterar det fångade mönstret till gemener, det finns också \U .

Kommentarer

  • du behöver inte göra detta – hela mönstret fångas alltid i &
  • Det är sant, men då skulle jag ha missat chansen att förklara att fånga matchningar 🙂

Svar

Utöver MvG: s svar kan du också använda Perl 6:

perl6 -pe .=lc temp

Här är $ _ implicit, och du behöver inte de enskilda offerten för att skydda den från expansion genom skalet ($ _ är en speciell Bash-parameter; se: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *