Programovanie

split príkaz pre DOS / Windows Via Groovy

Jedným z príkazov, ktorý mi pri práci v prostredí Windows / DOS najviac chýba z Linuxu, je príkaz split. Tento mimoriadne praktický príkaz umožňuje rozdeliť veľký súbor na niekoľko menších súborov, ktoré sú určené buď počtom riadkov, alebo počtom bajtov (alebo kilobajtov alebo megabajtov) požadovaným pre menšie súbory. Existuje mnoho využití týchto funkcií, napríklad prispôsobenie súborov na určité médium, zaistenie toho, aby boli súbory „čitateľné“ pre aplikácie s obmedzeniami dĺžky súborov atď. Bohužiaľ neviem o rozdelenom ekvivalente pre Windows alebo DOS. Na také niečo je možné skriptovať program PowerShell, ale táto implementácia je špecifická pre program PowerShell. K dispozícii sú aj produkty tretích strán, ktoré majú podobné funkcie. Tieto existujúce riešenia však ponechávajú iba toľko, koľko je potrebné, aby som mal motiváciu implementovať splitový ekvivalent v Groovy a to je predmetom tohto príspevku. Pretože Groovy beží na JVM, mohla by sa táto implementácia teoreticky spustiť na akomkoľvek operačnom systéme s modernou implementáciou Java Virtual Machine.

Na testovanie a demonštráciu rozdeleného skriptu založeného na Groovy je potrebný určitý typ zdrojového súboru. Použijem Groovy na ľahké vygenerovanie tohto zdrojového súboru. Nasledujúci jednoduchý skript Groovy, buildFileToSplit.groovy, vytvorí jednoduchý textový súbor, ktorý je možné rozdeliť.

#! / usr / bin / env groovy // // buildFileToSplit.groovy // // Prijíma jediný argument pre počet riadkov, ktoré sa majú zapísať do generovaného súboru. // Ak nie je zadaný žiadny počet riadkov, použije sa predvolené nastavenie 100 000 riadkov. // if (! args) {println "\ n \ nUsage: buildFileToSplit.groovy fileName lineCount \ n" println "kde fileName je názov súboru, ktorý sa má vygenerovať, a lineCount je" println "počet riadkov, ktoré sa majú vložiť do vygenerovaného spis. " System.exit (-1)} názov súboru = args [0] numberOfLines = args.length> 1? args [1] ako celé číslo: 100000 súbor = nový súbor (názov súboru) // vymaže výstupný súbor, ak už existuje súbor.delete () 1.upto (numberOfLines, {súbor << "Toto je riadok # $ {it}. \ n "}) 

Tento jednoduchý skript využíva implicitne dostupný „args“ handle Groovy na prístup k argumentom príkazového riadku pre skript buildFileToSplit.groovy. Potom vytvorí jeden súbor veľkosti založený na zadanom argumente počtu riadkov. Každý riadok je do značnej miery neoriginálny a je v ňom uvedené „Toto je riadok #“ a za ním číslo riadku. Nie je to efektný zdrojový súbor, ale funguje to ako príklad rozdelenia. Nasledujúca snímka obrazovky zobrazuje jeho chod a jeho výstup.

Vygenerovaný súbor source.txt vyzerá takto (tu sa zobrazuje iba jeho začiatok a koniec):

Toto je riadok # 1. Toto je riadok # 2. Toto je riadok # 3. Toto je riadok # 4. Toto je riadok # 5. Toto je riadok # 6. Toto je riadok # 7. Toto je riadok # 8. Toto je riadok # 9. Toto je riadok # 10. . . . Toto je riadok # 239. Toto je riadok # 240. Toto je riadok # 241. Toto je riadok # 242. Toto je riadok # 243. Toto je riadok # 244. Toto je riadok # 245. Toto je riadok # 246. Toto je riadok # 247. Toto je riadok # 248. Toto je riadok # 249. Toto je riadok # 250. 

Teraz je k dispozícii zdrojový súbor na rozdelenie. Tento skript je podstatne dlhší, pretože som ho nechal skontrolovať, či neobsahuje viac chybových stavov, pretože musí spracovávať viac parametrov príkazového riadku, a jednoducho preto, že robí viac ako skript, ktorý vygeneroval zdrojový súbor. Ďalej sa zobrazuje skript, ktorý sa jednoducho volá split.groovy:

#! / usr / bin / env groovy // // split.groovy // // Rozdelí jeden súbor na viac súborov podobne, ako funguje príkaz Unix / Linux split //. Táto verzia skriptu je určená iba pre textové súbory. // // Tento skript sa určitými spôsobmi líši od variantu Linux / Unix. Napríklad // výstupné správy tohto skriptu sa v niekoľkých prípadoch líšia a tento // skript vyžaduje, aby bol názov rozdeleného súboru uvedený ako argument // príkazového riadku a nebol poskytnutý ako // štandardný vstup . Tento skript tiež poskytuje voľbu „-v“ („--version“), ktorá nie je // inzerovaná pre verziu Linux / Unix. // // UPOZORNENIE: Tento skript je určený iba na ilustráciu použitia programu Groovy na // emuláciu príkazu skriptu Unix / Linux. Nie je určený na výrobu // ako je. Tento skript je navrhnutý tak, aby vytváral záložné kópie súborov generovaných // z rozdelenia jedného zdrojového súboru, ale // je vytvorená iba jedna záložná verzia // a je prepísaná ďalšími požiadavkami. // // //marxsoftware.blogspot.com/ // import java.text.NumberFormat NEW_LINE = System.getProperty ("line.separator") // // Na spracovanie argumentov príkazového riadku použite program Groovy CliBuilder // def cli = nový CliBuilder (použitie: 'split [OPTION] [INPUT [PREFIX]]') cli.with {h (longOpt: 'help', 'Usage Information') a (longOpt: 'suffix-length', type: Number, ' Použite prípony dĺžky N (predvolená hodnota je 2) ', args: 1) b (longOpt:' bajty ', typ: Number,' Veľkosť každého výstupného súboru v bajtoch ', args: 1) l (longOpt:' lines ', typ: Počet, 'Počet riadkov na výstupný súbor', args: 1) t (longOpt: 'verbose', 'Vytlačiť diagnostiku na štandardnú chybu tesne pred otvorením každého výstupného súboru', args: 0) v (verzia longOpt: ' ',' Výstupná verzia a ukončenie ', args: 0)} def opt = cli.parse (args) if (! Opt || opt.h) {cli.usage (); návrat} if (opt.v) {println "Verzia 0.1 (júl 2010)"; návrat} if (! opt.b &&! opt.l) {println "Zadajte dĺžku rozdelených súborov s počtom bajtov alebo počtom riadkov" cli.usage () return} if (opt.a &&! opt.a. isNumber ()) {println "Dĺžka prípony musí byť číslo"; cli.usage (); návrat} if (opt.b &&! opt.b.isNumber ()) {println "Veľkosť súborov v bajtoch musí byť číslo"; cli.usage (); návrat} if (opt.l &&! opt.l.isNumber ()) {println "Číslo riadku musí byť číslo"; cli.usage (); návrat} // // Určte, či budú rozdelené súbory dimenzované podľa počtu riadkov alebo počtu bajtov // súkromné ​​enum LINES_OR_BYTES_ENUM {BYTES, LINES} bytesOrLines = LINES_OR_BYTES_ENUM.LINES def príponaLength = opt.a? opt.a.toBigInteger (): 2 if (suffixLength 1? opt.arguments () [1]: "x" try {file = new File (filename) if (! file.exists ()) {println "Zdrojový súbor $ {filename} nie je platný zdrojový súbor. "System.exit (-4)} int fileCounter = 1 firstFileName =" $ {prefix} $ {fileSuffixFormat.format (0)} "if (verboseMode) {System.err.println "Vytvára sa súbor $ {firstFileName} ..."} outFile = createFile (firstFileName) if (bytesOrLines == LINES_OR_BYTES_ENUM.BYTES) {int byteCounter = 0 file.eachByte {if (byteCounter <numberBytes) {outFile << nový reťazec (it )} else {nextOutputFileName = "$ {prefix} $ {fileSuffixFormat.format (fileCounter)}" if (verboseMode) {System.err.println "Vytvára sa súbor $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << nový reťazec (it) fileCounter ++ byteCounter = 0} byteCounter ++}} else {int lineCounter = 0 file.eachLine {if (lineCounter <numberLines) {outFile << it << NEW_LINE} else {nextOutputFileName = "$ {prefix} $ {fileSuffixFormat.format (fileCounter)} " if (verboseMode) {System.err.println "Vytváranie súborov $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << it << NEW_LINE fileCounter ++ lineCounter = 0} lineCounter ++}}} catch (FileNotFoundException fnfEx) { println System.properties println "$ {fileName} nie je platný zdrojový súbor: $ {fnfEx.toString ()}" System.exit (-3)} catch (NullPointerException npe) {println "Vyskytla sa NullPointerException: $ {npe.toString ()} "System.exit (-4)} / ** * Vytvorte súbor s uvedeným názvom súboru. * * @param fileName Názov súboru, ktorý sa má vytvoriť. * @return Súbor vytvorený s uvedeným názvom; null, ak je uvedený názov null alebo * prázdny. * / def File createFile (String fileName) {if (! fileName) {println "Nemôžem vytvoriť súbor z prázdneho alebo prázdneho názvu súboru." return null} outFile = new File (fileName) if (outFile.exists ()) {outFile.renameTo (new File (fileName + ".bak")) outFile = new File (fileName)} return outFile} 

Tento skript je možné optimalizovať a lepšie modulovať, ale plní svoj účel demonštrácie toho, ako Groovy poskytuje pekný prístup k implementácii obslužných skriptov nezávislých na platforme.

Nasledujúca snímka obrazovky demonštruje použitie skriptu vstavanej podpory CLI od Groovy.

Nasledujúce dva snímky obrazovky demonštrujú rozdelenie zdrojového súboru na menšie súbory podľa počtu riadkov a bajtov (a s použitím rôznych možností prípony a názvu súboru). Prvý obrázok ukazuje, že tri výstupné súbory sú generované rozdelením do 100 riadkov (250 riadkov v zdrojovom súbore). Voľba -a určuje, že v názve súboru budú štyri celé čísla. Na rozdiel od rozdelenia systému Linux tento skript nezaručuje, že používateľom zadaný počet celých čísel je dostatočný na pokrytie počtu potrebných výstupných súborov.

Druhý obrázok (ďalší obrázok) zobrazuje skript, ktorý rozdeľuje zdrojový súbor na základe počtu bajtov a používa iný názov súboru a na číslovanie iba dve celé čísla.

Ako už bolo spomenuté vyššie, tento skript je „hrubý“. Mohlo by sa to vylepšiť z hľadiska samotného kódu, ako aj z hľadiska funkčnosti (rozšírené o lepšiu podporu binárnych formátov a zabezpečenie dostatočnej prípony mien súborov pre počet výstupných súborov). Skript tu však demonštruje jedno z mojich najobľúbenejších použití Groovy: písať skripty nezávislé na platforme pomocou známych knižníc Java a Groovy (SDK a GDK).

Tento príbeh, „split Command for DOS / Windows Via Groovy“, bol pôvodne publikovaný spoločnosťou JavaWorld.

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