Filtraggio e divisione di file di grandi dimensioni in base alla colonna di Windows


2

Ho circa 2 TB di file di dati formattati come

12/20/2015 somerandomdata
12/20/2015 somerandomdata
12/20/2015 somerandomdata
12/20/2015 somerandomdata
12/21/2015 somerandomdata
12/21/2015 somerandomdata
12/21/2015 somerandomdata
12/21/2015 somerandomdata
12/22/2015 somerandomdata
12/22/2015 somerandomdata
12/22/2015 somerandomdata
12/22/2015 somerandomdata

e voglio tirare fuori certe date. Ad esempio, potrei voler generare i file per il 20/12/2015 e il 22/12/2015.

12/20/2015 somerandomdata
12/20/2015 somerandomdata
12/20/2015 somerandomdata
12/20/2015 somerandomdata

e

12/22/2015 somerandomdata
12/22/2015 somerandomdata
12/22/2015 somerandomdata
12/22/2015 somerandomdata

Potrei facilmente farlo con grep in Linux facendo grep '12/20/2015' filein > fileout20e grep '12/22/2015' filein > fileout22ma questo ha due problemi.

Innanzitutto e, cosa più importante, deve generare due volte il ciclo di input per generare l'output. Con 2 TB di dati e diverse date per file, questo è un problema significativo. (Correlato: inoltre, non voglio soluzioni che suddividono il file in ogni data possibile perché non voglio i dati dalla maggior parte delle date, solo circa il 10% da ogni file di input)

Il secondo problema è che devo eseguirlo su Windows. (Mi rendo conto che la maggior parte dei comandi di Linux hanno un equivalente di Windows usando GnuWin32 o simili, quindi questo non è un grosso problema)

Esistono modi per farlo in modo efficiente?

EDIT: Le risposte finora hanno uno dei due problemi, quindi chiarirò un po '. Il primo problema è che non voglio scorrere più di una volta ciascuno dei file di input. Quindi, avere un ciclo per scorrere attraverso ciascuna delle date non funzionerà. Questo perché se avessi 200 date e 8000 file, occorrerebbero 1.600.000 iterazioni.

Il secondo problema è che voglio dividere ciascuno dei file di output in un file per data.

Quindi, con 200 date e 8000 file, dovrebbero esserci 1.600.000 file, ma con solo 8000 iterazioni del comando di ricerca.

EDIT 2: ecco una soluzione con i comandi di Linux. Probabilmente finirò per usarlo solo se qualcuno ha un modo migliore

grep -f 12/20/2015 12/22/2015 filein1 > intermediate
awk -F, '{print > $1".out"}' intermediate

Questo è un processo in due fasi che prima filtra le date e poi divide il risultato in base alla data.

Risposte:


4

Non voglio scorrere ciascuno dei file di input più di una volta.

Per scorrere attraverso ciascuna delle date non funzionerà. Voglio dividere ciascuno dei file di output in un file per data.

Oh, perché non hai detto semplicemente nessuna iterazione da un LOOP! ! . . .

Soluzione PowerShell

(Impostare le variabili di conseguenza nell'esempio seguente: elenco di stringhe, percorso del file di output e forse il nome della variabile stringa nel formato MMDDYYYY)

Select-String -Path "C:\Path\*.txt" -Pattern 12/20/2015,12/23/2015,12/30/2015 -AllMatches | foreach-object {
   $RS = $_.Matches[0].Groups[0].Value.Replace("/","")
   $RS | Out-File "C:\Path\$RS.txt" -Append
}

(Sopra è una soluzione PowerShell per cercare tutti i contenuti dei file di testo in una directory specifica rispetto a un elenco di stringhe. Inoltre, aggiungerà tutti i valori di stringa trovati a un file di output con un nome file valido che corrisponde al modello di stringa corrispondente, ed è univoco per quella stringa.)


Ecco una soluzione con i comandi di Linux. Probabilmente finirò per usarlo

grep -f 12/20/2015 12/22/2015 filein1 > intermediate

awk -F, '{print > $1".out"}' intermediate

Questo è un processo in due fasi che prima filtra le date e poi divide il risultato in base alla data.

Quindi stai cercando il contenuto dei file di testo in una determinata directory con un elenco di stringhe. Per ogni stringa corrispondente trovata in ciascun file, è necessario che il valore sia scritto (e aggiunto se applicabile) in un file con un nome file "valido" che sia univoco per la stringa, senza stringhe diverse negli stessi file.

Per quanto riguarda l'essere un modo "migliore" , è davvero una questione di opinione a seconda di ciò che stai misurando statistica e saggio delle risorse, suppongo. Non sapevo che fossi estremamente preoccupato per una soluzione performante ottimale rispetto al modo in cui qualcosa tendevi verso le opere.

(Terrò la soluzione di script batch di seguito nel caso in cui qualcuno la ritenga utile.)


Voglio tirare fuori certe date. Ad esempio, potrei voler generare i file per il 20/12/2015 e il 22/12/2015.

Commento

Tuttavia, a meno che non fraintenda findstr, ci sarà solo un file di output anziché uno per data, che non è il comportamento che sto cercando.

Questo si espanderà sul altra soluzione per darvi un nome di file di stringa da aggiungere al nome del file originale più la MMDDYYYYo YYYYMMDDo forse anche tutti i caratteri di combinazione o singoli del YYYY, MM, o DDparti della stringa corrispondente da aggiungere al nome del file di QUELLI stringhe trovate per file, proprio come hai spiegato.

Fondamentalmente devi solo impostare le tue variabili di conseguenza, salvare come uno script batch [.cmd] e quindi eseguirlo. La maggior parte delle variabili sarà esplicita nel percorso completo specifico delle directory applicabili.

Spiegazioni delle variabili di script batch

  • Il SET FilePath=valore sarà il percorso completo della posizione in cui si trovano i file .TXT che cercherete

  • Il SET StringList=valore sarà una posizione del percorso completo e un nome file in cui verrà salvato un file di testo con ciascuna stringa (ad es 12/20/2015. 12/22/2015, Ecc.) Da cercare nei .txtfile. Inserirai una stringa su ogni riga del file che verrà utilizzata come stringa per trovarla nei .txtfile (vedi esempio di seguito) .

  • Assumo le altre variabili e il resto della logica dello script batch ha senso; in caso contrario, fammi sapere e sarò felice di aggiungere ulteriori punti elenco per chiarire, ecc.


ESEMPIO SCRITTO A LOTTO

@ECHO ON

SET FilePath=C:\Path\<Location containing .TXT files to search>
SET StringList=C:\Path\DateList.txt

FOR %%A IN ("%FilePath%\*.txt") DO FOR /F "TOKENS=*" %%B IN (%StringList%) DO CALL :FindConCat "%%~B" "%%~NFXA" "%%~NA" "%%~XA"
GOTO EOF

:FindConCat
SET SearchStr=%~1
SET SearchFile=%~2
SET OutFName=%~3
SET FileExt=%~4
SET ParseStr=%SearchStr%
:::: --// MMDDYYY format
SET ParseStr=%ParseStr:~0,2%%ParseStr:~3,2%%ParseStr:~6,4%
:::: --// YYYYMMDD format
:: SET ParseStr=%ParseStr:~6,4%%ParseStr:~0,2%%ParseStr:~3,2%

FINDSTR /c:"%SearchStr%" "%SearchFile%">>"%FilePath%\%OutFName%_%ParseStr%%FileExt%"
GOTO EOF

ESEMPIO ELENCO FILE ELENCO CONTENUTO ( SET StringList=C:\Path\DateList.txt)

12/15/2015
12/22/2015
12/23/2015
12/24/2015

Non ho molta familiarità con lo script batch, ma penso di capire. Sembra un doppio ciclo annidato. Quindi, se avessi 40 file e 30 date, FINDSTR verrebbe eseguito 1200 volte. Vorrei qualcosa che esegue solo un FINDSTR o qualcosa di simile 40 volte, altrimenti la sceneggiatura impiegherà troppo tempo.
Jay,

Ho appena modificato la domanda per chiarire.
Jay,

Grande! Ho cercato di essere chiaro nella mia domanda originale, ma suppongo di no. Grazie!
Jay,

2

One-liner usando PowerShell:

get-content c:\filein.txt | where-object { $_ -match "12/22/2015" } | out-file c:\fileout22.txt


1
A meno che non mi manchi qualcosa, dovrò farlo per ogni data di cui ho bisogno. Quindi, se ho, diciamo, 200 per estrarre da ogni file, questo richiederà 200 volte il tempo che dovrebbe.
Jay,

Puoi aggiungere più date nel filtro o creare un semplice ciclo per fare praticamente tutto ciò di cui hai bisogno.
bentek,

Ma un ciclo richiederebbe molto più tempo. Vedi la mia modifica.
Jay,

2
findstr -rc:"12/2[02]/2015" filein > fileout

Non credo findstrche funzionerà molto bene con un file da 4 TB. Visualizza questa risposta Quali sono le funzionalità e i limiti non documentati del comando FINDSTR di Windows? .
DavidPostill

Ci sono circa 8000 file, ciascuno di circa 0,25 GB. Quindi, potrebbe non essere un problema.
Jay,

Tuttavia, a meno che non fraintenda findstr, ci sarà solo un file di output anziché uno per data, che non è il comportamento che sto cercando.
Jay,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.