Converteer de bestandsinhoud naar kleine letters

Ik heb een temp -bestand met wat kleine letters en hoofdletters.

Invoer

Inhoud van mijn temp bestand:

 hi Jigar GANDHI jiga  

Ik wil alle boven naar beneden converteren .

Commando

Ik probeerde het volgende commando:

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

maar kreeg verkeerde uitvoer.

Uitvoer

Ik wil het als:

hi jigar gandhi jiga 

Wat moet in het vervangende gedeelte zitten van argument voor sed?

Reacties

Answer

Als uw invoer alleen ASCII-tekens bevat, kunt u tr gebruiken zoals:

of (minder gemakkelijk te onthouden en IMO; maar niet beperkt tot Latijnse ASCII-letters, hoewel in sommige implementaties inclusief GNU tr, nog steeds beperkt tot tekens van één byte, dus in UTF-8-landinstellingen, nog steeds beperkt tot ASCII-letters):

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

als je sed moet gebruiken:

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

(hier uitgaande van de GNU-implementatie).

Met POSIX sed, zou je “alle transliteraties moeten specificeren en dan kun je kiezen welke letters die u wilt converteren:

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

Met awk:

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

Reacties

  • Merk op dat \L een GNU-extensie is.
  • \L werkt tot nu toe goed voor mij. En licht het punt toe dat je probeert om GNU extensie
  • @JigarGandhi te maken. sed is een Unix-commando. Verschillende systemen hebben verschillende varianten met verschillend gedrag en d functionaliteit. Gelukkig is er tegenwoordig ‘ een standaard die hier het meest aan voldoet, zodat u kunt rekenen op een minimum aan functies die iedereen gemeenschappelijk heeft. \L is er niet bij en werd geïntroduceerd door GNU sed (komt overeen met dezelfde operator in standaard ex / vi) en is over het algemeen niet beschikbaar in andere implementaties.
  • Merk op dat sommige tr implementaties zoals GNU tr niet ‘ werken niet correct in multi-byte landinstellingen (de meeste zijn tegenwoordig, probeer echo STÉPHANE | tr '[:upper:]' '[:lower:]' bijvoorbeeld). Op GNU-systemen geeft u misschien de voorkeur aan de sed variant of awk ‘ s tolower().
  • Kleine correctie: sed 's/.*/\L&/g' < input. De \1 verwijzing naar de overeenkomende deelstring zal ‘ niet werken, tenzij je de deelstring specificeert met haakjes zoals Wurtle doet in zijn. Het ‘ is echter iets schoner om & te gebruiken om de hele overeenkomst weer te geven, zoals weergegeven

Answer

Met vim is het supereenvoudig:

$ vim filename gg0guGZZ 

Opent het bestand gg gaat naar de eerste regel, 0, eerste kolom. Met guG , verlaagt het hoofdlettergebruik van alle tekens tot de onderkant van het bestand. ZZ slaat op en sluit af.

Het zou zo ongeveer alles moeten verwerken wat je erin gooit; het “ll negeer getallen, het” zal niet ASCII behandelen.

Als je het tegenovergestelde wilt doen, verander dan de kleine letters in hoofdletters, verwissel de u uit voor een U: gg0gUGZZ en je bent klaar.

Reacties

  • Lol ” super simpel ”
  • dit doet duidelijk niet ‘ t goed schalen voor veel bestanden
  • @CoreyGoldberg vim file1 file2 fileetc en dan iets als :bufdo gg0guG:w<CR> zou waarschijnlijk werken voor een willekeurig aantal bestanden. Heb dat echter niet getest!
  • @TankorSmash dat nog steeds niet ‘ opschaalt naar een groot aantal bestanden

Antwoord

Zelf vind ik dd hiervoor leuk.

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

… krijgt …

hi jigar ghandi jiga 

De LC_ALL=C is om alle multibytes in invoer te beschermen – hoewel multibyte-hoofdletters niet worden geconverteerd. Hetzelfde geldt voor (GNU) tr – beide apps zijn gevoelig voor invoerverminking in elke niet-C-landinstelling. iconv kan met beide worden gecombineerd voor een uitgebreide oplossing.

De 2>/dev/null omleiding verwijdert het standaardstatusrapport van dd “- en zijn status. Zonder dd zou volgen op voltooiing van een taak zoals de bovenstaande met afdrukinformatie zoals hoeveel bytes werden verwerkt enz.

Opmerkingen

  • Deze oplossing is veel sneller dan tr bij het verwerken van grote bestanden, bedankt!

Antwoord

Je kunt ook Perl 5 gebruiken:

perl -pe "$_=lc" temp 

De optie -p vertelt perl om de gespecificeerde uitdrukking één keer uit te voeren voor elke invoerregel, waarbij het resultaat wordt afgedrukt, dwz de laatste waarde van $_. -e geeft aan dat de programma zal het volgende argument zijn, in tegenstelling tot een bestand dat het script bevat. lc converteert naar kleine letters. Zonder argument werkt het op $_. En $_= slaat dat opnieuw op zodat het wordt afgedrukt.

Een variatie daarvan zou zijn

perl -ne "print lc" temp 

-n is als -p behalve dat $_ uiteindelijk niet wordt afgedrukt. Dus in plaats van op te slaan in die variabele, voeg ik een expliciete printinstructie toe.

Een voordeel van Perl in tegenstelling tot sed is dat je geen GNU-extensies nodig hebt. Er zijn projecten die compatibel moeten zijn met niet-GNU-omgevingen, maar die ook al een afhankelijkheid van Perl hebben. In vergelijking met tr, kan het zijn dat Perl lc gemakkelijker locaalbewust gemaakt kan worden. Zie de perllocale man-pagina voor details.

Antwoord

Je moet vastleggen het overeenkomende patroon en gebruik het dan in de vervanging met een modifier:

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

De \(...\) “vangt” de met overeenkomende tekst, de eerste opname gaat naar \1, de volgende naar \2, enz. De nummering is volgens de openingshaakjes in het geval van geneste opnames.

De \L converteert het vastgelegde patroon naar kleine letters, er is ook \U voor hoofdletters .

Reacties

  • je hoeft dit niet te doen – het hele patroon zit altijd in &
  • Klopt, maar dan had ik de kans gemist om het vastleggen van overeenkomsten uit te leggen 🙂

Antwoord

Naast het antwoord van MvG, zou je ook Perl 6 kunnen gebruiken:

perl6 -pe .=lc temp

Hier is $ _ impliciet, en je hebt geen enkele aanhalingstekens nodig om het te beschermen tegen uitbreiding door de shell ($ _ is een speciale Bash-parameter; zie: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *