Konverter filindhold til små bogstaver

Jeg har temp -fil med noget små og store bogstaver.

Input

Indholdet af min temp fil:

 hi Jigar GANDHI jiga  

Jeg vil konvertere alle øvre til nedre .

Kommando

Jeg prøvede følgende kommando:

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

men fik forkert output.

Output

Jeg vil have det som:

hi jigar gandhi jiga 

Hvad skal der være i erstatning delen af argument for sed?

Kommentarer

Svar

Hvis din input kun indeholder ASCII-tegn, kan du bruge tr som:

eller (mindre let at huske og skrive IMO; men ikke begrænset til ASCII latinske bogstaver, dog i nogle implementeringer inklusive GNU tr, stadig begrænset til enkeltbyte-tegn, så i UTF-8-lokaliteter, stadig begrænset til ASCII-bogstaver):

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

hvis du skal bruge sed:

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

(her forudsat GNU-implementering).

Med POSIX sed skal du angive alle translitterationer, og derefter kan du vælge hvilken bogstaver, du vil konvertere:

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

Med awk:

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

Kommentarer

  • Bemærk, at \L er en GNU-udvidelse.
  • \L fungerer hidtil godt for mig. En lys det punkt, du prøver at lave GNU-udvidelse
  • @JigarGandhi. sed er en Unix-kommando. Forskellige systemer har forskellige varianter med forskellig opførsel og d funktionalitet. Heldigvis er der i dag ‘ en standard, der passer mest til, så du kan stole på et minimum af funktioner, der er fælles for alle. \L er ikke blandt dem og blev introduceret af GNU sed (matcher den samme operator i standard ex / vi) og er generelt ikke tilgængelig i andre implementeringer.
  • Bemærk, at nogle tr implementeringer som GNU tr don ‘ t fungerer korrekt i multi-byte-lokaliteter (de fleste af dem er i dag, prøv echo STÉPHANE | tr '[:upper:]' '[:lower:]' for eksempel). På GNU-systemer foretrækker du muligvis sed -varianten eller awk ‘ s tolower().
  • Let korrektion: sed 's/.*/\L&/g' < input. \1 henvisningen til den matchede understreng vandt ‘ t, medmindre du angiver understrengen med parentes, som wurtle gør i sin. Det er dog ‘ lidt renere at bruge & til at repræsentere hele kampen, som vist

Svar

Ved hjælp af vim er det super simpelt:

$ vim filename gg0guGZZ 

Åbner filen gg går til første linje, 0, første kolonne. Med guG , sænker tilfældet med alle tegn, indtil bunden af filen. ZZ gemmer og afsluttes.

Det skal håndtere næsten alt, hvad du kaster på det; det “ll ignorerer tal, det” håndterer ikke ASCII.

Hvis du vil gøre det modsatte, skal du dreje de små bogstaver til store bogstaver, bytte u ud for en U: gg0gUGZZ og du er indstillet.

Kommentarer

  • Lol ” super simpelt ”
  • dette

t skaler godt for mange filer

  • @CoreyGoldberg vim file1 file2 fileetc og så ville noget som :bufdo gg0guG:w<CR> sandsynligvis arbejde for et vilkårligt antal filer. Har dog ikke testet det!
  • @TankorSmash der stadig ikke ‘ t skaleres til et stort antal filer
  • Svar

    Jeg kan godt lide dd til dette selv.

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

    … får …

    hi jigar ghandi jiga 

    LC_ALL=C er for at beskytte multibytes i input – selvom multibyte-hovedstæder ikke konverteres. Det samme gælder for (GNU) tr – begge apps er tilbøjelige til at indtaste mangler i ethvert ikke-C-land. iconv kan kombineres med enten til en omfattende løsning.

    2>/dev/null omdirigeringen kasserer dd “s standardstatusrapport – og dens stderr. Uden den dd ville følge færdiggørelsen af et job som ovenstående m / udskrivningsoplysninger som hvor mange byte der blev behandlet osv.

    Kommentarer

    • Denne løsning er langt hurtigere end tr når du håndterer store filer, tak!

    Svar

    Du kan også bruge Perl 5:

    perl -pe "$_=lc" temp 

    Indstillingen -p fortæller perl for at køre det angivne udtryk en gang for hver linie med input og udskrive resultatet, dvs. den endelige værdi af $_. -e angiver, at programmet bliver det næste argument i modsætning til en fil, der indeholder scriptet. lc konverterer til små bogstaver. Uden et argument fungerer det på $_. Og $_= gemmer det igen, så det bliver udskrevet.

    En variation af det ville være

    perl -ne "print lc" temp 

    Brug af -n er som -p bortset fra at $_ ikke bliver udskrevet i sidste ende. Så i stedet for at gemme i denne variabel inkluderer jeg en eksplicit udskriftserklæring.

    En fordel ved Perl i modsætning til sed er, at du ikke har brug for nogen GNU-udvidelser. Der er projekter, der skal være kompatible med miljøer, der ikke er GNU, men som også allerede har Perl en afhængighed. Sammenlignet med tr kan det være, at Perl lc lettere kan gøres lokalbevidst. Se perllocale man-siden for detaljer.

    Svar

    Du skal fange det matchede mønster, og brug det derefter til erstatning med en modifikator:

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

    \(...\) “fanger” omslutter matchet tekst, den første optagelse går til \1, den næste til \2 osv. Nummereringen er i henhold til åbningsbeslag i tilfælde af nestede optagelser.

    \L konverterer det fangede mønster til små bogstaver, der er også \U til store bogstaver .

    Kommentarer

    • du behøver ikke gøre dette – hele mønsteret er altid fanget i &
    • Sandt, men så ville jeg have gået glip af muligheden for at forklare fangstkampe 🙂

    Svar

    Ud over MvGs svar kan du også bruge Perl 6:

    perl6 -pe .=lc temp

    Her er $ _ implicit, og du behøver ikke de enkelte anførselstegn for at beskytte det mod udvidelse af skallen ($ _ er en speciel Bash-parameter; se: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )

    Skriv et svar

    Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *