Konverter filinnhold til små bokstaver

Jeg har temp -fil med noe små og store bokstaver.

Inngang

Innholdet i temp -filen:

 hi Jigar GANDHI jiga  

Jeg vil konvertere alle øvre til nedre .

Kommando

Jeg prøvde følgende kommando:

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

men fikk feil utgang.

Utgang

Jeg vil ha det som:

hi jigar gandhi jiga 

Hva som må være i erstatning delen argument for sed?

Kommentarer

Svar

Hvis innspillene bare inneholder ASCII-tegn, kan du bruke tr som:

eller (mindre lett å huske og skrive IMO; men ikke begrenset til ASCII latinske bokstaver, men i noen implementeringer inkludert GNU tr, fremdeles begrenset til enkeltbyte-tegn, så i UTF-8 lokaliteter, fremdeles begrenset til ASCII-bokstaver):

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

hvis du må bruke sed:

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

(her forutsatt GNU-implementeringen).

Med POSIX sed, trenger du å spesifisere alle translitterasjonene, og deretter kan du velge hvilken bokstaver du vil konvertere:

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

Med awk:

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

Kommentarer

  • Vær oppmerksom på at \L er en GNU-utvidelse.
  • \L fungerer bra for meg så langt. En lys det punktet at du prøver å lage GNU-utvidelse
  • @JigarGandhi. sed er en Unix-kommando. Ulike systemer har forskjellige varianter med ulik oppførsel og d funksjonalitet. Heldigvis er det i dag ‘ en standard som passer mest, slik at du kan stole på et minimum sett med funksjoner som er felles for alle. \L er ikke blant dem og ble introdusert av GNU sed (samsvarer med samme operator i standard ex / vi) og er vanligvis ikke tilgjengelig i andre implementeringer.
  • Merk at noen tr implementeringer som GNU tr ikke ‘ t fungerer ordentlig på flere byte-steder (de fleste av dem er i dag, prøv echo STÉPHANE | tr '[:upper:]' '[:lower:]' for eksempel). På GNU-systemer foretrekker du kanskje sed -varianten eller awk ‘ s tolower().
  • Lett korreksjon: sed 's/.*/\L&/g' < input. \1 referansen til den matchede understrengen vant ‘ t, med mindre du spesifiserer understrengen med parentes slik wurtle gjør i sin. Det er imidlertid ‘ litt renere å bruke & for å representere hele kampen, som vist

Svar

Ved hjelp av vim er det superenkelt:

$ vim filename gg0guGZZ 

Åpner filen, gg går til første linje, 0, første kolonne. Med guG , senker saken til alle tegnene til bunnen av filen. ZZ lagrer og går ut.

Den skal håndtere omtrent alt du kaster på den; den «vil ignorere tall, det» vil håndtere ikke ASCII.

Hvis du ville gjøre det motsatte, snu de små bokstavene til store bokstaver, bytt u ut for en U: gg0gUGZZ og du er klar.

Kommentarer

  • Lol » superenkelt »
  • dette gjør åpenbart ikke ‘ t skalere godt for mange filer
  • @CoreyGoldberg vim file1 file2 fileetc og da ville noe sånt som :bufdo gg0guG:w<CR> sannsynligvis / i> arbeid for et hvilket som helst antall filer. Har ikke testet det skjønt!
  • @TankorSmash som fremdeles ikke ‘ t skalerer til et stort antall filer

Svar

Jeg liker dd for dette selv.

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

… blir …

hi jigar ghandi jiga 

LC_ALL=C er for å beskytte alle multibytes i inngangen – selv om multibytehovedsteder ikke blir konvertert. Det samme gjelder (GNU) tr – begge appene er tilbøyelige til å legge inn mangler i alle ikke-C-land. iconv kan kombineres med enten for en omfattende løsning.

2>/dev/null omdirigering forkaster dd «s standardstatusrapport – og dens stderr. Uten den dd vil følge gjennomføring av en jobb som ovenfor med utskriftsinformasjon som hvor mange byte som ble behandlet og så videre.

Kommentarer

  • Denne løsningen er mye raskere enn tr når du håndterer store filer, takk!

Svar

Du kan også bruke Perl 5:

perl -pe "$_=lc" temp 

Alternativet -p forteller perl for å kjøre det angitte uttrykket en gang for hver linje med inndata, og skrive ut resultatet, dvs. den endelige verdien av $_. -e indikerer at programmet blir neste argument, i motsetning til en fil som inneholder skriptet. lc konverterer til små bokstaver. Uten argument vil det fungere på $_. Og $_= lagrer det igjen slik at det blir skrevet ut.

En variant av det ville være

perl -ne "print lc" temp 

Bruk av -n er som -p bortsett fra at $_ ikke blir skrevet ut til slutt. Så i stedet for å lagre i den variabelen, inkluderer jeg en eksplisitt utskrift.

En fordel med Perl i motsetning til sed er at du ikke trenger noen GNU-utvidelser. Det er prosjekter som må være kompatible med miljøer som ikke er GNU, men som også allerede har en avhengighet av Perl. Sammenlignet med tr, kan det være at Perl lc lettere kan gjøres lokalbevisst. Se perllocale man-siden for detaljer.

Svar

Du må fange det matchede mønsteret, og bruk det deretter til erstatning med en modifikator:

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

\(...\) «fanger» vedlegger samsvarende tekst, går den første opptaket til \1, den neste til \2 osv. Nummereringen er i henhold til åpningsparenteser i tilfelle nestede opptak.

\L konverterer det fangede mønsteret til små bokstaver, det er også \U for store bokstaver .

Kommentarer

  • du trenger ikke gjøre dette – hele mønsteret er alltid fanget i &
  • Sant, men da ville jeg ha gått glipp av muligheten til å forklare å fange kamper 🙂

Svar

I tillegg til MvGs svar kan du også bruke Perl 6:

perl6 -pe .=lc temp

Her er $ _ implisitt, og du trenger ikke de enkelte anførselstegnene for å beskytte den mot utvidelse av skallet ($ _ er en spesiell Bash-parameter; se: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *