Programmering

delt kommando for DOS / Windows Via Groovy

En av kommandoene jeg savner mest fra Linux når jeg jobber i Windows / DOS-miljøer er delt kommando. Denne ekstremt praktiske kommandoen gjør det mulig å dele en stor fil i flere mindre filer bestemt av spesifikasjonen av enten antall linjer eller antall byte (eller kilobyte eller megabyte) som er ønsket for de mindre filene. Det er mange bruksområder for slik funksjonalitet, inkludert å tilpasse filer på visse medier, gjøre filer "lesbare" av applikasjoner med fillengdebegrensninger og så videre. Dessverre er jeg ikke klar over en delt ekvivalent for Windows eller DOS. PowerShell kan skriptes for å gjøre noe slikt, men den implementeringen er spesifikk for PowerShell. Det er også tredjepartsprodukter tilgjengelig som har lignende funksjonalitet. Imidlertid lar disse eksisterende løsningene akkurat nok være å være ønsket om at jeg har motivasjonen til å implementere en split ekvivalent i Groovy, og det er gjenstand for dette innlegget. Fordi Groovy kjører på JVM, kan denne implementeringen teoretisk kjøres på ethvert operativsystem med en moderne Java Virtual Machine-implementering.

For å teste og demonstrere det Groovy-baserte delte skriptet, er det nødvendig med en eller annen type kildefil. Jeg bruker Groovy til å enkelt generere denne kildefilen. Følgende enkle Groovy-skript, buildFileToSplit.groovy, oppretter en enkel tekstfil som kan deles.

#! / usr / bin / env groovy // // buildFileToSplit.groovy // // Godtar enkeltargument for antall linjer som skal skrives til generert fil. // Hvis det ikke er angitt et antall linjer, bruker standard 100.000 linjer. // if (! args) {println "\ n \ nBruk: buildFileToSplit.groovy fileName lineCount \ n" println "der fileName er navnet på filen som skal genereres og lineCount er" println "antall linjer som skal plasseres i den genererte fil." System.exit (-1)} fileName = args [0] numberOfLines = args.length> 1? argumenterer [1] som Heltall: 100000 fil = ny fil (filnavn) // sletter utdatafilen hvis den allerede eksisterte file.delete () 1.upto (numberOfLines, {file << "Dette er linje # $ {it}. \ n "}) 

Dette enkle skriptet bruker Groovys implisitt tilgjengelige "args" -håndtak for å få tilgang til kommandolinjeargumenter for buildFileToSplit.groovy-skriptet. Deretter oppretter den en enkelt fil med størrelse basert på angitt antall linjer. Hver linje er stort sett uoriginal og sier "Dette er linje #" etterfulgt av linjenummeret. Det er ikke en fancy kildefil, men den fungerer for splitteeksemplet. Det neste skjermbildet viser at det er kjørt og utdataene.

Den genererte source.txt-filen ser slik ut (bare begynnelsen og slutten av den vises her):

Dette er linje 1. Dette er linje nr. 2. Dette er linje nr. 3. Dette er linje 4. Dette er linje 5. Dette er linje 6. Dette er linje 7. Dette er linje 8. Dette er linje 9. Dette er linje nr. 10. . . . Dette er linje 239. Dette er linje 240. Dette er linje 241. Dette er linje 242. Dette er linje 243. Dette er linje 244. Dette er linje 245. Dette er linje 246. Dette er linje 247. Dette er linje 248. Dette er linje 249. Dette er linje # 250. 

Det er nå en kildefil som kan deles. Dette skriptet er betydelig lenger fordi jeg har fått det til å se etter flere feilforhold, fordi det må håndtere flere kommandolinjeparametere, og rett og slett fordi det gjør mer enn skriptet som genererte kildefilen. Skriptet, bare kalt split.groovy, vises neste:

#! / usr / bin / env groovy // // split.groovy // // Del enkeltfil i flere filer på samme måte som Unix / Linux split // kommando fungerer. Denne versjonen av skriptet er kun ment for tekstfiler. // // Dette skriptet skiller seg ut fra Linux / Unix-varianten på visse måter. For eksempel, er dette skriptets utgangsmeldinger forskjellige i flere tilfeller, og dette // skriptet krever at navnet på filen som deles er gitt som et // kommandolinjeargument i stedet for å gi muligheten til å gi det som // standardinngang . Dette skriptet gir også et "-v" ("--version") alternativ som ikke // er annonsert for Linux / Unix-versjonen. // // FORSIKTIG: Dette skriptet er kun ment som en illustrasjon på hvordan du bruker Groovy til å // etterligne Unix / Linux-skriptkommandoen. Det er ikke ment for produksjon // bruk som det er. Dette skriptet er laget for å lage sikkerhetskopier av filer som er generert // fra splitting av en enkelt kildefil, men bare en sikkerhetskopieringsversjon er // opprettet og overstyres av ytterligere forespørsler. // // //marxsoftware.blogspot.com/ // import java.text.NumberFormat NEW_LINE = System.getProperty ("line.separator") // // Bruk Groovy's CliBuilder til behandling av kommandolinjeargument // def cli = ny CliBuilder (bruk: 'split [OPTION] [INPUT [PREFIX]]'] cli.with {h (longOpt: 'help', 'Usage Information') a (longOpt: 'suffix-length', type: Number, ' Bruk suffikser med lengden N (standard er 2) ', args: 1) b (longOpt:' bytes ', type: Number,' Size of each output file in bytes ', args: 1) l (longOpt:' lines ', type: Antall, 'Antall linjer per utdatafil', args: 1) t (longOpt: 'verbose', 'Skriv ut diagnostisk til standardfeil rett før hver utdatafil åpnes', args: 0) v (longOpt: 'versjon ',' Output version and exit ', args: 0)} def opt = cli.parse (args) if (! Opt || opt.h) {cli.usage (); return} if (opt.v) {println "Versjon 0.1 (juli 2010)"; return} hvis (! opt.b &&! opt.l) {println "Angi lengden på delte filer med enten antall byte eller antall linjer" cli.usage () return} hvis (opt.a &&! opt.a. isNumber ()) {println "Suffikslengden må være et tall"; cli.usage (); return} if (opt.b &&! opt.b.isNumber ()) {println "Filstørrelse i byte må være et tall"; cli.usage (); return} hvis (opt.l &&! opt.l.isNumber ()) {println "Linjenummer må være et tall"; cli.usage (); return} // // Bestem om delte filer vil bli størrelse etter antall linjer eller antall byte // private enum LINES_OR_BYTES_ENUM {BYTES, LINES} bytesOrLines = LINES_OR_BYTES_ENUM.LINES def suffixLength = opt.a? opt.a.toBigInteger (): 2 if (suffiksLengde 1? opt.arguments () [1]: "x" prøv {file = new File (filnavn) hvis (! file.exists ()) {println "Kildefil $ {filnavn} er ikke en gyldig kildefil. "System.exit (-4)} int fileCounter = 1 firstFileName =" $ {prefix} $ {fileSuffixFormat.format (0)} "if (verboseMode) {System.err.println "Opprette fil $ {firstFileName} ..."} outFile = createFile (firstFileName) if (bytesOrLines == LINES_OR_BYTES_ENUM.BYTES) {int byteCounter = 0 file.eachByte {if (byteCounter <numberBytes) {outFile << new String (it )} annet {nextOutputFileName = "$ {prefiks} $ {fileSuffixFormat.format (fileCounter)}" hvis (verboseMode) {System.err.println "Opprette fil $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << ny streng (it) fileCounter ++ byteCounter = 0} byteCounter ++}} annet {int lineCounter = 0 file.eachLine {if (lineCounter <numberLines) {outFile << it << NEW_LINE} annet {nextOutputFileName = "$ {prefiks} $ {fileSuffixFormat.format (fileCounter)} " hvis (verboseMode) {System.err.println "Opprette fil $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << it << NEW_LINE fileCounter ++ lineCounter = 0} lineCounter ++}}} fangst (FileNotFoundException fnfEx) { println System.properties println "$ {fileName} er ikke en gyldig kildefil: $ {fnfEx.toString ()}" System.exit (-3)} fangst (NullPointerException npe) {println "NullPointerException oppdaget: $ {npe.toString ()} "System.exit (-4)} / ** * Opprett en fil med det oppgitte filnavnet. * * @param fileName Navnet på filen som skal opprettes. * @return File opprettet med det oppgitte navnet; null hvis navnet er null eller * tomt. * / def File createFile (String fileName) {if (! fileName) {println "Kan ikke opprette en fil fra et null eller tomt filnavn." return null} outFile = new File (fileName) if (outFile.exists ()) {outFile.renameTo (new File (fileName + ".bak")) outFile = new File (fileName)} return outFile} 

Dette skriptet kan optimaliseres og bedre moduleres, men det oppfyller formålet med å demonstrere hvordan Groovy gir en fin tilnærming for implementering av plattformuavhengige verktøyskript.

Det neste skjermbildet viser skriptets bruk av Groovys innebygde CLI-støtte.

De neste to skjermbildene viser å dele kildefilen i mindre filer etter henholdsvis linjenumre og byte (og ved hjelp av forskjellige alternativ for suffiks og filnavn). Det første bildet viser at tre utdatafiler genereres når de deles i 100 linjer (250 linjer i kildefilen). Alternativet -a spesifiserer at fire heltallplasser vil være i filnavnet. I motsetning til Linux-splittelsen garanterer ikke dette skriptet at det antall brukere som er gitt av brukeren er tilstrekkelig til å dekke antall nødvendige utdatafiler.

Det andre bildet (neste bilde) viser skriptet som deler kildefilen basert på antall byte og bruker et annet filnavn og bare to heltall for nummereringen.

Som nevnt ovenfor er dette skriptet et "grovt snitt." Det kan forbedres når det gjelder selve koden så vel som når det gjelder funksjonalitet (utvidet til bedre støtte for binære formater og for å sikre at filnavnssuffikser er tilstrekkelig lange for antall utdatafiler). Imidlertid viser skriptet her en av mine favorittbruk av Groovy: å skrive plattformuavhengige skript ved hjelp av velkjente Java- og Groovy-biblioteker (SDK og GDK).

Denne historien, "split Command for DOS / Windows Via Groovy" ble opprinnelig utgitt av JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found