Sziasztok!
Tudtok arra könnyű megoldást, hogy egy Text file-t bizonyos sorszámok között több text fájlra bontsuk?
A lenti kóddal azt próbálom megállapítani, hogy mik legyenek azok a bizonyos sorszámok.
Érdemes az egész fájlt beolvasni egy String Array-be vagy fölösleges?
public static void main(String[] args) {
Path file = Paths.get("C:/Users/pXXXX/Desktop/O_XXXX1027_0XXX35");
int LineNumber = 1;
List intList = new ArrayList();
try (InputStream in = Files.newInputStream(file);
BufferedReader reader =
new BufferedReader(new InputStreamReader(in))) {
String line;
while ((line = reader.readLine()) != null ) {
if (line.startsWith("EDI_DC40")) {
System.out.println(line);
intList.add(LineNumber);
}
LineNumber++;
}
} catch (IOException x) {
System.err.println(x);
}
for (Integer i : intList) {
System.out.println("LineNumber: " + i);
}
}
- 2885 megtekintés
Hozzászólások
Mekkora a fájl? Mi az hogy bizonyos sorszámok között? Itt úgy tűnik a sor eleje jelzi, hogy mit akarsz belőle kiszedni.
Én ahány fájlt létre akarnék hozni, annyi listát készítenék, raknám a listákba a megfelelő sorokat, és a végén minden listát kiírnék fájlba. A fájl beolvasásakor a sorokat már szétpakolnám, minek lássam egyben az egészet.
- A hozzászóláshoz be kell jelentkezni
Vannak a fájlban EDI_DC40 -nel kezdődő sorok.
Ezek a sorok jelzik a különálló részeket.
Addig tart egy rész amíg nem találkozok még egy EDI_DC40-es sorral, de akkor az már a következő rész első sora lesz.
Az utolsó rész ugye EDI_DC40-el keződik és a null lesz a vége, amikor véget ér a fájl.
Ezzel küzdök már pár napja, de eddig csak részeredményeim vannak.
String listákat készítenél?
A readline() metódus megfelelő amivel próbálkozok?
Nem igazán vagyok tapasztalt programozó, de ezzel tudok tanulni legalább.
Köszi!
- A hozzászóláshoz be kell jelentkezni
Attól függ mekkora az az állomány. :)
Én így csinálnám ha a memória nem akadály:
<?php
$darabok=preg_split('/(^|\n)EDI_DC40/',file_get_contents("file.txt"));
unset($darabok[0]); // az első EDI_DC40 előtti dolog nem érdekel
foreach ($darabok as $darab) echo "EDI_DC40".$darab."\n\n";
De nem programozóként dolgozom még mielőtt valaki beleköt (és tudom nem Java de gondolom ott is van hasonló). :P
- A hozzászóláshoz be kell jelentkezni
A fenti valami ilyesmi lenne Java-ba:
import java.util.Scanner;
import java.io.File;
public class thing {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner( new File("file.txt") ).useDelimiter("(^|\n)EDI_DC40");
while(sc.hasNext()) System.out.println("EDI_DC40"+sc.next());
};
};
Bár azt nem tudom, hogy lehetne kiszűrni, hogy az első EDI_DC40 előtti szöveget ne adja vissza eredményként (a PHP üres elemet ad vissza először akkor is ha az állomány EDI_DC40-el kezdődik, míg a Java valamiért nem)
- A hozzászóláshoz be kell jelentkezni
ugyan bash de esetleg így is jó?
csplit nagyfile 'minta' {*} -ks
- A hozzászóláshoz be kell jelentkezni
Ez gagyi!
Nincsen benne ojjektum. ;)
- A hozzászóláshoz be kell jelentkezni
input megnyitása
output = null
for (;;) {
sor olvasása inputból
if (vége az inputnak) {
ha output != null: output bezárás
break
}
if (új rész kezdődik) {
ha output != null: output bezárás
új output megnyitása
}
sor írása outputba
}
input bezárás
profit
Vagy valami ilyesmi. Ennek méret nem akadály, extraként kezeli az üres fájlokat is. Ha a fájl nem a szekció kezdő sorral kezdődik, azon direkt elszáll NPE-vel a ciklus legvégén.
- A hozzászóláshoz be kell jelentkezni
package valami.fajl.darabolo;
import java.io.*;
public class FajlDarabolo {
private static final String SOURCE = "C:/Users/pXXXX/Desktop/O_XXXX1027_0XXX35";
private static final String FP = "C:/Users/pXXXX/Desktop/O_XXXX1027_0XXX35-";
private static final String SEP = "EDI_DC40";
private static final String NL = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
int i = 1;
BufferedWriter bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
BufferedReader br = new BufferedReader(new FileReader(SOURCE));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith(SEP)) {
bw.close();
bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
}
bw.write(line + NL);
}
bw.close();
br.close();
}
}
- A hozzászóláshoz be kell jelentkezni
Köszönöm! Ez működik!! Én még azóta se tudtam megírni normálisra.
Egyedül csak annyi a baja, hogy mivel az első sor nekem rögtön EDI_DC40 -vel kezdődik a fájlban, az elején létrejön egy üres fájl, amiben csak egy sortörés van, így az i index is 1-gyel több, mint kéne neki.
Nem tudom, hogy ezt a végén kéne kitörölni, vagy már elején valahogy megtudnám neki adni, hogy ha az első sor rögtön EDI_DC40-nel kezdődik, akkor nyugodtan írjon tovább tovább a következő olyanig.
- A hozzászóláshoz be kell jelentkezni
Kicsit belegányolva (nem próbáltam, nem vagyok benne biztos, hogy jó, sry):
int i = 1;
BufferedWriter bw = null;
BufferedReader br = new BufferedReader(new FileReader(SOURCE));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith(SEP) && i != 1) {
bw.close();
bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
} else {
bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
}
bw.write(line + NL);
}
--
blogom
- A hozzászóláshoz be kell jelentkezni
Továbbgányoltam (de én se próbáltam ki :)
int i = 1;
BufferedWriter bw = null;
BufferedReader br = new BufferedReader(new FileReader(SOURCE));
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith(SEP)) {
if (i!=1) bw.close();
bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
} else if (i==1) continue;
bw.write(line + NL);
}
- A hozzászóláshoz be kell jelentkezni
jujj. egyrészt ettől gotofail érzésem van, másrészt a
if (i == 1)
ág szerintem nem kell oda. (elsőnek anélkül volt, nem?)
most az első fájlba nem kerül bele majd a separator, de az összes többibe igen.
--
blogom
- A hozzászóláshoz be kell jelentkezni
Igen anélkül volt, csak azért került be mertha nem separatorral kezdődik a file akkor nullba írt volna (és tudom, hogy ronda, de hosszú volt a nap :))
De azt nem értem első fájlba így miért nem került bele a separator?
A tiedet is csak azért próbáltam átírni mert úgy tűnt, hogy a javított minden sort külön fájlba ír az else ág miatt, de lehet benéztem. :)
- A hozzászóláshoz be kell jelentkezni
egyrészt jogos, az enyém minden sort külön fájlba ír - ú, de csúnyán benéztem. :-D
(OP: azt hiszem, ezt nem fogom megjavítani, mert csak még jobban beégek - de elméletileg az else után egy if-fel javítható :-D)
A tied, meg a SEP:
jogos, ezt is benéztem, belekerül a SEP. De ha nem SEP-pel kezdődik, akkor nem kerül bele semmi az első SEP-ig. Talán. De mostmár nem merek semmit mondani - tesztet kéne rá írni :-P
--
blogom
- A hozzászóláshoz be kell jelentkezni
Igaz, azt elhagyja, nem tudtam szüksége van-e rá, de ha igen:
s/continue;/bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
Bár lehet ettől mégjobban elromlik. :-P
- A hozzászóláshoz be kell jelentkezni
int i = 1;
BufferedReader br = new BufferedReader(new FileReader(SOURCE));
String line = br.readLine();
if (line == null || !line.startsWith(SEP)) {
System.err.println("Nem " + SEP + " -el kezdodik!");
return;
}
BufferedWriter bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
bw.write(line + NL);
while ((line = br.readLine()) != null) {
if (line.startsWith(SEP)) {
bw.close();
bw = new BufferedWriter(new FileWriter(FP + i++ + ".txt"));
}
bw.write(line + NL);
}
bw.close();
br.close();
Ez lehetett volna egy házi feladat, de most már mindegy :)
- A hozzászóláshoz be kell jelentkezni
Köszönöm!
Átolvastam. Szerintem ez így jó lesz.
Este ki is próbálom :)
Köszi
- A hozzászóláshoz be kell jelentkezni
#!/usr/bin/python
import sys
fname=sys.argv[1]
i=1
f=open(fname+str(i),"w")
for sor in open(fname, "r"):
if sor[:8] == "EDI_DC40":
f.close()
f=open(fname+str(i),"w")
i+=1
continue
f.write(sor)
f.close()
- A hozzászóláshoz be kell jelentkezni
Igazából, nem vagyok otthon pythonban úgyhogy lehet hülyeséget kérdezek, de az a continue (nem hagyja le miatta pont az EDI... sort a kiírásból?) kell oda?
- A hozzászóláshoz be kell jelentkezni
Ha ki akarod írni az EDI_DC40 szót, mint szeparátor szót is, akkor ennek elhagyásával megteheted. Sőt ha marad a continue, akkor azt is megteheted, hogy például előtte sorban
...
f.write(sor[8:])
continue
...
amely hatására az EDI_DC40 szó lemarad, viszont a vele egy sorban levő többi tartalom mégis a text fájlba kerül. Tehát bármi a célod, innenntől kezdve ujjgyakorlat.
- A hozzászóláshoz be kell jelentkezni
Értem és köszönöm :) Ha sok szabad időm lesz majd töltök el vele, elegáns. :)
- A hozzászóláshoz be kell jelentkezni
Érdekes, hogy mindenki jávázni meg pythonozni kezd, holott pont ilyesmire van kitalálva a klasszikus unix-os awk.
awk '/EDI_DC40/{ f="File"++i".txt"; } { print > f; }' input.txt
Természetesen a kezdő regexp-et ki lehet cserélni tetszőlegesre.
Know your tools!
- A hozzászóláshoz be kell jelentkezni
Egyébként +1
- A hozzászóláshoz be kell jelentkezni
Én ebből a sorból arra tippelek, hogy a kérdezőnek windows-a van:
Path file = Paths.get("C:/Users/pXXXX/Desktop/O_XXXX1027_0XXX35");
Azon meg nem szokott lenni AWK, szóval egyáltalán nem természetes hogy egyből awk-ra gondol a windows user. Amúgy +1 meg minden :)
- A hozzászóláshoz be kell jelentkezni
Hát operációsrendszert választani tudni kell :-)
Amúgy ha Windowson lennék, valószínűleg hiányoznának ezek a toolok, szóval keresnék rá megoldást, és mintha a cygwin (?) vagy mSys (?) hozta volna az alap toolokat.
- A hozzászóláshoz be kell jelentkezni
PowerShell? (tudom gusztustalan első probálkozásom vele és a regex nem jó, nem tudom milyen formát szeretne :P)
Get-Content("File.txt") | Out-String | %{
$j=1;
$x=[regex]::split($_,"EDI_DC40");
Foreach($z in $x) {
$z="EDI_DC40"+$z;
Out-File -filepath $j -inputobject $z -Encoding default; $j++;
}
};
- A hozzászóláshoz be kell jelentkezni
Tejóég /o\
Akkor-Inkább::python
- A hozzászóláshoz be kell jelentkezni
Hát ha winen nem szokott lenni AWK, akkor tessék rá telepíteni Perl-t, és a fenti kódra ráengedni az a2p -t, és valahogy így használni:
a2p fenti.awk | perl
- A hozzászóláshoz be kell jelentkezni
+1.
Igen, az awk-n is gondolkoztam, de sajnos ez Windows 7.
Eddig notepad++-ban kézzel vágtam szét ezeket a fájlokat, de most szeretnék rá írni valami kis programot :)
Amiket itt kaptam ötleteket nagyon hasznosak!
Köszönöm mindenkinek!
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
Unixon? Mert akkor hívd meg a split parancsot :-)
- A hozzászóláshoz be kell jelentkezni
Nemrég ismerkedtem meg az Ammonite-tal:
Gondoltam hátha valakit érdekel, hogyan néz ki ebben:
val lines = read.lines! wd/"edi.txt"
val results = lines.foldLeft(List("")){ case (b :: tail, a) =>
if (a.startsWith("EDI_DC40"))
a :: b :: tail
else
((b + "\r\n" + a) :: tail)
}
results.reverse.tail.zipWithIndex.foreach {
case (content, idx) =>
write(s"edi$idx.txt", content)
}
Powershelleshez hasonló megoldás:
val content = read! wd/"edi.txt"
val results = content.split("EDI_DC40")
results.tail.zipWithIndex.foreach {
case (content, idx) =>
write(s"edi$idx.txt", "EDI_DC40" + content)
}
- A hozzászóláshoz be kell jelentkezni
Na mondom ez olyan, mint ha a verbose c++/javaba lenne beleerőszakolva valami funkcionális hányás, erre látom ez scala. Ahaaa!!! :-)
- A hozzászóláshoz be kell jelentkezni
Pontosan! Most már lehet scala-ban shell scripteket írni. :-)
- A hozzászóláshoz be kell jelentkezni