Caricare e modificare file testo

di il
4 risposte

Caricare e modificare file testo

Buongiorno a tutti,
ho un problema che non riesco a risolvere e non essendo espertissimo di matlab chiedo aiuto a voi . Ho un file di testo, da utilizzare come input per un programma di analisi strutturale (opensees), che devo modificare in automatico con uno script di matlab. Sostanzialmente dovrei caricare il file testo, ricercare un gruppo di righe e modificarle, chiudere il file testo e salvare in un nuovo file. Questo in loop dovrei farlo (immagino con un ciclo for) in modo tale da creare un determinato numero di file testo diversi tra di loro. La domanda è come faccio a operare sui file testo? Caricarlo, ricercare le righe da modificare, modificarle e salvare?? Grazie mille per l'aiuto

4 Risposte

  • Re: Caricare e modificare file testo

    La domanda è troppo generica.

    MatLab non è il linguaggio ideale per processare file di testo, salvo casi particolari (es. CSV, file con di dati con formato uniforme).
    Ci sono, tuttavia, molte funzioni disponibili per la lettura / scrittura di files di testo, la scelta delle quali dipende dalla struttura dei dati all'interno del file.

    Dovresti, per lo meno, fornire un esempio del contenuto del file che vuoi modificare e come.
  • Re: Caricare e modificare file testo

    Ciao, grazie e scusami nel ritardo della risposta. Allora ho un file testo (estensione .tcl) di questo tipo:

    # beam_column_elements forceBeamColumn
    # Geometric transformation command
    geomTransf Linear 1
    element forceBeamColumn 1 1 11 1 Lobatto 2 5
    # Geometric transformation command
    geomTransf Linear 2
    element forceBeamColumn 2 11 12 2 Lobatto 2 5
    # Geometric transformation command
    geomTransf Linear 3
    element forceBeamColumn 3 12 13 3 Lobatto 2 5
    # Geometric transformation command

    Sostanzialmente dovrei importarlo in matlab (qui sorge la prima domanda, con che comando?? perchè ne ho provato diversi ma senza un buon esito), in tante colonne quanti sono gli elementi, sia stringhe che numeri. In questo caso ad esempio sono 9 colonne. Però dal testo dovrei eliminare le righe che iniziano con # perchè non mi servono. E non capisco come lavorare sulle colonne dato che non sono 9 su ogni riga. Questo è il primo problema che non riesco a risolvere
  • Re: Caricare e modificare file testo

    La prima cosa da fare è cercare di individuare una struttura ripetitiva nel file di input in modo che questo possa essere letto in maniera ricorsiva da uno script.
    Se l'esempio che hai pubblicato è significativo dei files che devi gestire, si può notare che, a parte le righe che cominciano con "#" e che devono essere scartate,
    [*] c'è sempre una riga con i termini "geomTransf" e "Linear" seguiti da un numero intero che sembra incrementare ad ogni ricorrenza
    [*] subito dopo c'è sempre una riga con i termini "element" eforceBeamColumn" seguiti da quattro numeri interi; questi, a loro volta, sono seguiti dal termine "Lobatto" che precede due numeri interi

    Se la struttura identificata è corretta si potrebbe:
    [*] aprire in lettura il file di testo con la funzione "fopen"
    [*] creare un ciclo while "infinito" (while (1))all'interno del quale leggere il file riga per riga co la funzione "fgetl"
    [*] i ciclo while verrà interrotto quando sarà stata letta l'ultima riga del file di input
    [*] la funzione "fgetl" ritorna un array di caratteri per cui sarà sufficiente verificare se il primo carattere sia "#" per poter identificare la riga da scartare
    [*] se la riga non contiene "#" come primo carattere, la si può scandire con la funzione "textscan" per allocare in un cellarray il suo contenuto
    [*] se il primo elemento del cellarray contiene il termine "geomTransf" siamo in presenza della prima delle due righe "utili"
    [*] si po', quindi" estrarre dall'ultimo elemento del cellarray la striga che contiene il valore numerico e convertirlo, appunto, in un numero
    [*] con un'altra chiamata alla funzione "fgetl" si può quindi leggere la seconda riga "utile"
    [*] come per la prima, si può scandire la riga con la funzione "textscan" ed allocarne le vare parti ad un cellarray
    [*] a questo punto si possono estrarre i due set di valori numerici dal cellarray ed assegnarli a due matrici
    [*] per fare questo si può sfruttare il fatto che il valore numerico presente nella prima riga "utile" sembra incrementarsi ogni volta. Se è così, lo si può utilizzare come indice della riga della matrice nella quale inserire i valori estratti. Nel caso il valore numerico non si incrementasse ogni volta, potrebbe essere sostituito da un contatore
    [*] al termine della lettura del file di input, questo va chiuso con la chiamata alla funzione "fclose".

    Nell'esempio che segue, le due matrici sono state chiamate, rispettivamente, "forceBeamColumn" e "Lobatto" per richiamare i termini ai quali i valori sono riferiti.

    Il processo descritto sopra vale solo nel caso l'esempio del file che hai pubblicato sia effettivamente rappresentativo del contenuto e della struttura; in caso contrario, per variazioni minori, non dovrebbe esser troppo difficile modificare lo script.
    Per differenze maggiori occorre, invece, analizzare attentamente il file alla ricerca di una struttura ripetitiva.

    I commenti nel codice dovrebbero chiarire i vari passaggi.
    
    % Open the input file
    fp=fopen('in.txt','rt');
    % Loop over the input file
    while(1)
    %  Read a line
       riga=fgetl(fp)
    %  Check for the endf of file
       if(~isnumeric(riga))
    %     If the the line strats with # discard it
          if(riga(1) ~= '#')
    %        Scan the line
             s=textscan(riga','%s')
    %        if the first word is "geomTransf"
             if(strcmp(s{1}(1),'geomTransf'))
    %           Extract from the line the value of "Linear"
                Linear=(str2num(char(s{1}(3))))
    %           Read the next line\
                riga=fgetl(fp)
    %           Scan the line
                tmp=textscan(riga,'%s %s %f %f %f %f %s %f %f')
    %           Extract from the line the value of "forceBeamColumn" and "Lobatto"
                forceBeamColumn(Linear,1:4)=double([tmp{3:6}])
                Lobatto(Linear,1:2)=double([tmp{8:9}])
             end
          end
       else
    %     Exit the loop at the end of file
          break
       end
    end
    % Close the input file
    fclose(fp)
    
  • Re: Caricare e modificare file testo

    Grazie mille sei stato utilissimo.
Devi accedere o registrarti per scrivere nel forum
4 risposte