Programování

split příkaz pro DOS / Windows Via Groovy

Jedním z příkazů, které mi při práci v prostředí Windows / DOS nejvíce chybí z Linuxu, je příkaz split. Tento mimořádně praktický příkaz umožňuje rozdělit velký soubor na několik menších souborů, které jsou určeny specifikací buď počtem řádků, nebo počtem bajtů (nebo kilobajtů nebo megabajtů) požadovaných pro menší soubory. Existuje mnoho použití takových funkcí, včetně přizpůsobení souborů na určitá média, zpřístupnění souborů „čitelnosti“ aplikacemi s omezením délky souborů atd. Bohužel nevím o děleném ekvivalentu pro Windows nebo DOS. PowerShell lze skriptovat, aby něco takového udělal, ale tato implementace je specifická pro PowerShell. K dispozici jsou také produkty třetích stran, které mají podobné funkce. Tato stávající řešení však ponechávají jen tolik, aby bylo žádoucí, abych měl motivaci implementovat splitový ekvivalent v Groovy a to je předmětem tohoto příspěvku. Protože Groovy běží na JVM, mohla by být tato implementace teoreticky spuštěna na jakémkoli operačním systému s moderní implementací Java Virtual Machine.

K otestování a předvedení děleného skriptu založeného na Groovy je vyžadován nějaký typ zdrojového souboru. Pro snadné generování tohoto zdrojového souboru použiji Groovy. Následující jednoduchý skript Groovy, buildFileToSplit.groovy, vytvoří jednoduchý textový soubor, který lze rozdělit.

#! / usr / bin / env groovy // // buildFileToSplit.groovy // // Přijme jediný argument pro počet řádků, které mají být zapsány do generovaného souboru. // Pokud není zadán žádný počet řádků, použije se výchozí hodnota 100 000 řádků. // if (! args) {println "\ n \ nUsage: buildFileToSplit.groovy fileName lineCount \ n" println "kde fileName je název generovaného souboru a lineCount je" println "počet řádků, které mají být vloženy do generovaného soubor." System.exit (-1)} fileName = args [0] numberOfLines = args.length> 1? args [1] jako Celé číslo: 100000 soubor = nový Soubor (název souboru) // vymaže výstupní soubor, pokud již existuje soubor.delete () 1. až (numberOfLines, {soubor << "Toto je řádek # $ {it}. \ n "}) 

Tento jednoduchý skript používá implicitně dostupný "args" popisovač Groovy pro přístup k argumentům příkazového řádku pro skript buildFileToSplit.groovy. Poté vytvoří jeden soubor o velikosti na základě zadaného argumentu počet řádků. Každý řádek je do značné míry neoriginální a uvádí „Toto je řádek #“ a za ním číslo řádku. Není to efektní zdrojový soubor, ale funguje to pro příklad rozdělení. Následující snímek obrazovky ukazuje jeho běh a jeho výstup.

Vygenerovaný soubor source.txt vypadá takto (zde se zobrazuje pouze jeho začátek a konec):

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

Nyní je k dispozici zdrojový soubor k rozdělení. Tento skript je výrazně delší, protože jsem jej nechal zkontrolovat více chybových podmínek, protože potřebuje zpracovat více parametrů příkazového řádku a jednoduše proto, že dělá víc než skript, který generoval zdrojový soubor. Skript, jednoduše nazvaný split.groovy, je zobrazen dále:

#! / usr / bin / env groovy // // split.groovy // // Rozdělte jeden soubor na více souborů podobně, jak funguje příkaz Unix / Linux split //. Tato verze skriptu je určena pouze pro textové soubory. // // Tento skript se určitým způsobem liší od varianty Linux / Unix. Například // výstupní zprávy tohoto skriptu se v několika případech liší a tento // skript vyžaduje, aby byl název rozdělovaného souboru poskytován jako argument // příkazového řádku, místo aby poskytoval možnost // standardní vstup . Tento skript také poskytuje možnost „-v“ („--version“), která není // inzerována pro verzi Linux / Unix. // // UPOZORNĚNÍ: Tento skript je určen pouze pro ilustraci použití nástroje Groovy k // emulaci příkazu skriptu Unix / Linux. Není určen pro produkci // použití tak, jak je. Tento skript je navržen tak, aby vytvářel záložní kopie souborů generovaných // z rozdělení jednoho zdrojového souboru, ale je vytvořena pouze jedna záložní verze // a je přepsána dalšími požadavky. // // //marxsoftware.blogspot.com/ // import java.text.NumberFormat NEW_LINE = System.getProperty ("line.separator") // // Pro zpracování argumentů příkazového řádku použijte nástroj Groovy CliBuilder // def cli = new CliBuilder (usage: 'split [OPTION] [INPUT [PREFIX]]') cli.with {h (longOpt: 'help', 'Usage Information') a (longOpt: 'suffix-length', type: Number, ' Použijte příponu délky N (výchozí hodnota je 2) ', args: 1) b (longOpt:' bajty ', typ: Number,' Velikost každého výstupního souboru v bajtech ', args: 1) l (longOpt:' lines ', typ: Number, 'Number of lines per output file', args: 1) t (longOpt: 'verbose', 'Print diagnostic to standard error just before each output file is opened', args: 0) v (longOpt: 'version ',' Výstupní verze a ukončení ', args: 0)} def opt = cli.parse (args) if (! Opt || opt.h) {cli.usage (); návrat} if (opt.v) {println "Verze 0.1 (červenec 2010)"; návrat} if (! opt.b &&! opt.l) {println "Zadejte délku rozdělených souborů buď s počtem bytů, nebo počtem řádků" cli.usage () return} if (opt.a &&! opt.a. isNumber ()) {println "Délka přípony musí být číslo"; cli.usage (); návrat} if (opt.b &&! opt.b.isNumber ()) {println "Velikost souborů v bajtech musí být číslo"; cli.usage (); návrat} if (opt.l &&! opt.l.isNumber ()) {println "Číslo řádku musí být číslo"; cli.usage (); návrat} // // Určete, zda budou rozdělené soubory dimenzovány podle počtu řádků nebo počtu bytů // soukromé výčet LINES_OR_BYTES_ENUM {BYTES, LINES} bytesOrLines = LINES_OR_BYTES_ENUM.LINES def příponaLength = opt.a? opt.a.toBigInteger (): 2 if (suffixLength 1? opt.arguments () [1]: "x" try {file = new File (filename) if (! file.exists ()) {println "Source file $ {filename} není platný zdrojový soubor. "System.exit (-4)} int fileCounter = 1 firstFileName =" $ {prefix} $ {fileSuffixFormat.format (0)} "if (verboseMode) {System.err.println "Vytváření souboru $ {firstFileName} ..."} outFile = createFile (firstFileName) if (bytesOrLines == LINES_OR_BYTES_ENUM.BYTES) {int byteCounter = 0 file.eachByte {if (byteCounter <numberBytes) {outFile << nový řetězec (it )} else {nextOutputFileName = "$ {prefix} $ {fileSuffixFormat.format (fileCounter)}" if (verboseMode) {System.err.println "Vytváření souboru $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << nový Řetězec (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áření souboru $ {nextOutputFileName} ..."} outFile = createFile (nextOutputFileName) outFile << it << NEW_LINE fileCounter ++ lineCounter = 0} lineCounter ++}}} catch (FileNotFoundException fnfEx) { println System.properties println "$ {fileName} není platný zdrojový soubor: $ {fnfEx.toString ()}" System.exit (-3)} catch (NullPointerException npe) {println "došlo k NullPointerException: $ {npe.toString ()} "System.exit (-4)} / ** * Vytvořte soubor s uvedeným názvem. * * @param fileName Název souboru, který má být vytvořen. * @return Soubor vytvořený s uvedeným názvem; null, pokud je zadaný název null nebo * prázdný. * / def Soubor createFile (řetězec fileName) {if (! fileName) {println "Nelze vytvořit soubor z prázdného nebo prázdného názvu souboru." return null} outFile = nový soubor (název souboru) if (outFile.exists ()) {outFile.renameTo (nový soubor (název souboru + ".bak")) outFile = nový soubor (název souboru)} návratový soubor} 

Tento skript lze optimalizovat a lépe modulovat, ale plní svůj účel demonstrace toho, jak Groovy poskytuje pěkný přístup k implementaci obslužných skriptů nezávislých na platformě.

Následující snímek obrazovky ukazuje, jak skript používá integrovanou podporu CLI Groovy.

Další dva snímky obrazovky ukazují rozdělení zdrojového souboru na menší soubory podle čísel řádků a bajtů (a použití různých možností přípon a názvů souborů). První obrázek ukazuje, že tři výstupní soubory jsou generovány při rozdělení na 100 řádků (250 řádků ve zdrojovém souboru). Možnost -a určuje, že v názvu souboru budou čtyři celočíselná místa. Na rozdíl od rozdělení Linuxem tento skript nezaručuje, že počet celých čísel poskytovaných uživatelem je dostatečný k pokrytí počtu nezbytných výstupních souborů.

Druhý obrázek (další obrázek) ukazuje skript rozdělující zdrojový soubor na základě počtu bajtů a použití jiného názvu souboru a pouze dvou celých čísel pro číslování.

Jak bylo uvedeno výše, tento skript je „hrubým střihem“. Mohlo by to být vylepšeno jak z hlediska samotného kódu, tak z hlediska funkčnosti (rozšířeno o lepší podporu binárních formátů a ujištění, že přípony názvů souborů jsou dostatečně dlouhé pro počet výstupních souborů). Skript zde však ukazuje jedno z mých oblíbených použití Groovy: psát skripty nezávislé na platformě pomocí známých knihoven Java a Groovy (SDK a GDK).

Tento příběh, „split Command pro DOS / Windows Via Groovy“, původně publikoval JavaWorld.

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