Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλημερα, έχω μια λίστα της μορφής

0 -121.904167 41.974556
1 -122.902153 44.974766
2 -117.896790 40.988075
...

και θέλω να γράψω ένα προγραμματάκι ή script-ακι που να το μετατρέπει σε csv, δλδ κάτι τέτοιο

0; -121.904167; 41.974556
1; -122.902153; 44.974766
2; -117.896790; 40.988075
...

Επίσης υπάρχουν αρκετές γραμμές όπου μπορεί να υπάρχει νούμερο μόνο στην "1η στήλη" κι όχι στις άλλες 2.

 

Οπότε αυτό που θέλω να ρωτήσω είναι την λογική που πρέπει να χρησιμοποιήσω. Προσπάθησα να το κάνω σε R (γιατί δεν γνωρίζω και κάτι καλύτερο). Κάνω parse, αλλάζω white spaces  με ";" αλλά μου χαλάει στην έξοδο. Μετά προσπάθησα να περάσω την λίστα σε πίνακες αλλά σκάει όταν βρει γραμμές που δεν αποτελούνται από 3 στοιχεία, αλλά 1. Οπότε πρέπει να κάνω παράλληλα και καποιο καθάρισμα, και να πετάξω αυτές τις γραμμές.

 

Σκέφτομαι να ξεκινήσω μια προσπάθεια σιγά σιγά σε java, που ίσως είναι πιο proper για τη δουλεια που θέλω, αλλά γενικά ψάχνω στο ποιος είναι ο σωστός τρόπος-μεθοδολογια εν γένη, για την δουλεια αυτή.

 

ps: το αρχείο αποτελείται από καμιά 20.000 γραμμές, ενώ ο σκοπός δεν είναι τόσο η υλοποίηση του τελικού csv (το κάνω μπακαλίστικα με ένα εξελ ή sublime) αλλά να μάθω, πως να γράψω ένα τέτοιο script-ακι. Αν και χρήστης macOS δεν το έχω καθόλου με terminal, που φαντάζομαι γίνεται κι απο εκει.

Δημοσ.

Αν είσαι σίγουρος ότι έτσι θα είναι όλες οι γραμμές, τότε απλά πρέπει να διαβάζεις κάθε γραμμής τα στοιχεία και να τα γράφεις στο άλλο αρχείο. Για παράδειγμα, σε C:

int a;
double b, c;

while (fscanf(inputFile, "%d%lf%lf", &a, &b, &c) == 3) {
    fprintf(outputFile, "%d; %.6f; %.6f\n", a, b, c);
}

Αν από την άλλη αλλάζουν όπως είπες, τότε πρέπει να γίνει αλλιώς. Αυτός ο κώδικας διαβάζει όλη τη γραμμή και προσπαθεί από αυτή να διαβάσει το πολύ τρία πράγματα:

int a;
double b, c;
char lineBuffer[MAX_SIZE];

while (fgets(lineBuffer, MAX_SIZE - 1, inputFile)) {
    a = b = c = 0;
    if (sscanf(lineBuffer, "%d%lf%lf", &a, &b, &c) != 0) {
        fprintf(outputFile, "%d; %.6f; %.6f\n", a, b, c);
    }
}

Δεν ήξερα τι ήθελες να κάνεις αν έχει μόνο ένα αριθμό, οπότε το έβαλα να εκτυπώνει μηδενικά.

Disclaimer: Δε ξέρω αν δουλεύει, δεν το δοκίμασα.

 

Εννοείται ότι τα παραπάνω είναι κομμάτια κώδικα και όχι ολόκληρο πρόγραμμα.

Δημοσ.

Προφανώς το παπί έχει τον πιο απλό και γρήγορο τρόπο, αλλά μιας και έχουμε μία καυτή μέρα:

 

Με notepad++ και regex replace (υποθέτω και άλλοι editors θα υποστηρίζουν αντίστοιχη λειτουργία):

 

Find what: ^(\d+)\s+(\-?\d+\.?\d+)\s+(\-?\d+\.?\d+)|^(\d+)\s+

Replace with: (?{1}\1;\2;\3:)

 

Ναι, ναι, now you have two problems.

 

Edit: Αλλαγή μιας και είδα πως θες να αφαιρείς τις γραμμές που έχουν έναν αριθμό μόνο.

Δημοσ.

thanks για τις απαντησεις. Γενικα η ιδεα όπως έγραψα πιο πανω είναι να το υπολοιήσω με script κι όχι με text editor, πιο πολυ γιατι μετα από αυτό έρχεται άλλο πιο δυσκολο ερωτημα, που πρεπει να απαντησω και που λογικα απαιτει προγραμματισμο.

Δημοσ.

Αν μπορείς να χρησιμοποιήσεις python κοίτα το https://docs.python.org/3/library/csv.html

 

Στο συγκεκριμένο παράδειγμα που δίνεις

το παρακάτω κάνει δουλειά
import csv
with open('test.csv', newline='') as csvin, open('test2.csv', 'w', newline='') as csvout:
	data = csv.reader(csvin, delimiter=' ', quoting=csv.QUOTE_NONNUMERIC)
	csv.writer(csvout, delimiter=';', quoting=csv.QUOTE_NONNUMERIC ).writerows(data)

Υπάρχει όμως ένα μικρό πρόβλημα ότι δεν σου επιτρέπει να έχεις delimiter μεγαλύτερο του ενός χαρακτήρα 

δηλαδή θα πάρεις τα data σου

0;-121.904167;41.974556
1;-122.902153;44.974766
2;-117.896790;40.988075

αντί

0; -121.904167; 41.974556
1; -122.902153; 44.974766
2; -117.896790; 40.988075
  • Like 1
Δημοσ.

Προφανώς το παπί έχει τον πιο απλό και γρήγορο τρόπο, αλλά μιας και έχουμε μία καυτή μέρα:

 

Με notepad++ και regex replace (υποθέτω και άλλοι editors θα υποστηρίζουν αντίστοιχη λειτουργία):

 

Find what: ^(\d+)\s+(\-?\d+\.?\d+)\s+(\-?\d+\.?\d+)|^(\d+)\s+

Replace with: (?{1}\1;\2;\3:)

 

Ναι, ναι, now you have two problems.

 

Edit: Αλλαγή μιας και είδα πως θες να αφαιρείς τις γραμμές που έχουν έναν αριθμό μόνο.

 

Θα μπορούσε να γίνει πιο άπλα το regex για να μη είναι άλλο ένα πρόβλημα

'\b(\s)\b' και αντικατάσταση αυτό που θέλει '; '

Θα πάρει δηλαδή μόνο το κενό και θα το αντικαταστήσει με ερωτηματικό κενό

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...