Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Dateien in Verzeichnissen finden

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Terence09



Anmeldungsdatum: 19.11.2020
Beiträge: 4

BeitragVerfasst am: 19.11.2020, 15:24    Titel: Dateien in Verzeichnissen finden Antworten mit Zitat

Hallo,

ich schreibe ein Programm welches HTML Dateien abändern soll.
Diese befinden sich in 300 Ordnern, welche wiederum in einem Hauptordner sind. Teilweise auch in noch mehr Unterordnern.
Jede Datei die gefunden werden soll heisst index.htm

Wie kann man in FREEBASIC alle Ordnernamen auflisten?
Dann z.b auf die erste index.Datei im ersten Ordner zugreifen?
Dann den zweiten usw...

Das Tool müsste sich also vom Hauptverzeichnis reinhangeln und jede Datei finden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
hhr



Anmeldungsdatum: 15.07.2020
Beiträge: 19

BeitragVerfasst am: 19.11.2020, 19:18    Titel: Antworten mit Zitat

Vielleicht kann
https://www.freebasic-portal.de/porticula/ordnerinhalte-auflisten-open-pipe-1850.html
weiterhelfen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4370
Wohnort: ~/

BeitragVerfasst am: 19.11.2020, 19:23    Titel: Antworten mit Zitat

Ansonsten hätte ich noch eine handgeschriebene Rekursion im Angebot:

Code:
#include once "dir.bi"

sub such(pfad as string, gesuchteDatei as string, ergebnis(any) as string)
  print "durchsuche " & pfad
  dim as integer attribute
  dim as string datei = dir(pfad & "\*.*", fbNormal or fbDirectory, attribute)
  dim as string ordner()
  do while len(datei)
    if datei = "." or datei = ".." then
      ' Ordner . und .. ueberspringen
      datei = dir("",, attribute)
      continue do
    end if
    if attribute and fbDirectory then
      ' Ordner an die Ordnerliste anhaengen
      redim preserve ordner(ubound(ordner)+1)
      ordner(ubound(ordner)) = datei
    elseif datei = gesuchteDatei then
      ' Datei gefunden
      redim preserve ergebnis(ubound(ergebnis)+1)
      ergebnis(ubound(ergebnis)) = pfad & "\" & datei
    end if
    datei = dir("",, attribute)
  loop
  for i as integer = 0 to ubound(ordner)
    ' alle Ordner in der Ordnerliste rekursiv weiter durchsuchen
    such(pfad & "\" & ordner(i), gesuchteDatei, ergebnis())
  next
end sub

redim ergebnis() as string
such "C:\Users\", "index.htm", ergebnis()

print
print "gefundene Dateien:"
for i as integer = 0 to ubound(ergebnis)
  print ergebnis(i)
next


Ständig die Arraygröße im Einerschritt zu vergrößern ist ja nicht ganz so der feine Stil, aber da kann man ja dann etwas feilen.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1050
Wohnort: Ruhrpott

BeitragVerfasst am: 19.11.2020, 23:42    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
Ständig die Arraygröße im Einerschritt zu vergrößern ist ja nicht ganz so der feine Stil, aber da kann man ja dann etwas feilen.
Das Feilen ist unnötig, einmal ausreichend dimensionieren oder schrittweise erweitern macht keinen messbaren Unterschied.

Hier die Routine, die ich seit Jahren benutze, um solche Dateilisten zu erstellen (soll heissen: Ist erprobt und funktioniert lächeln ). Das Programm durchsucht das startverzeichnis und sämtliche Unterverzeichnisse nach passenden Dateien. DateiListe() enthält danach die vollständige Liste aller gesuchten Dateien, DirListe() unter demselben Index den dazugehörigen Pfad.
Code:
#Include "vbcompat.bi"

Declare Sub ListeErstellen(startverzeichnis As String, dateimaske As String = "*", erweiterung As String = ".*")

ReDim Shared As String SubDirListe(1), DirListe(1), DateiListe(1)
Dim As Integer x

ListeErstellen("d:\basic\freebasic", "*", ".bas")

Print UBound(DirListe);" Verzeichnisse"
Print UBound(DateiListe);" Dateien"

Print
Print

'liste aller gefundenen dateien mit pfad erstellen
Open "c:\dateiliste.txt" For Output As #1
  For x = 1 To UBound(dateiliste)
    Print #1, dirliste(x);"   ";dateiliste(x)
  Next
Print #1,x 
Close

Print "OK"

Sleep
End

Sub ListeErstellen(startverzeichnis As String, dateimaske As String = "*", erweiterung As String = ".*")
   
   Dim As Integer startindex, maxindex, x, y
   Dim As String verzeichnis, g
   
   startindex = 1
   
  verzeichnis = startverzeichnis 'zu durchsuchendes verzeichnis aus ini-datei einlesen
  '?verzeichnis
  If Len(verzeichnis) Then 'neues verzeichnis
    'variablen initialisieren
    startindex = UBound(SubDirListe)+1 'array um einen platz vergrößern
    maxindex = startindex
    ReDim Preserve SubDirListe(startindex)
    SubDirListe(startindex) = verzeichnis
    Do
      For x = startindex To maxindex 'alle neu dazugekommenen
        g = Dir(SubDirListe(x) + "\*", fbDirectory) '1. unterverzeichnis
        Do While Len(g) 'neues unterverzeichnis gefunden
          Select Case g
            Case ".",".."
              'ignorieren
            Case Else
              ReDim Preserve SubDirListe(UBound(SubDirListe) + 1) 'array um einen platz vergrößern
              SubDirListe(UBound(SubDirListe)) = SubDirListe(x) + "\" + g 'neues unterverzeichnis mit pfad in array schreiben
          End Select
          g = Dir("", fbDirectory) 'nächstes unterverzeichnis
        Loop
      Next
      If UBound(SubDirListe) = maxindex Then 'kein neues unterverzeichnis dazugekommen
        Exit Do
      Else 'zeiger für nächsten durchlauf setzen
        startindex = maxindex + 1 'beginn der neu gefundenen unterverzeichnisse
        maxindex = UBound(SubDirListe) 'zeiger auf ende des arrays
      EndIf
    Loop
  EndIf 
      
   'Open "c:\subdirliste.txt" For Output As #1
   '  For x = 1 To UBound(SubDirListe)
   '    Print #1, SubDirListe(x)
   '  Next
   'Close
   
   'liste aller gesuchten dateien erstellen
   ReDim DateiListe(0)
   ReDim DirListe(0)
   ? UBound(SubDirListe); " Unterverzeichnisse"
   For x = 1 To UBound(SubDirListe) 'alle unterverzeichnisse
     g = Dir(subdirliste(x) + "\" + dateimaske + erweiterung,&H37 - fbDirectory) '1. datei / alle dateien ohne verzeichnisse
     Do While Len(g) 'wenn datei gefunden
      ReDim Preserve dateiliste(UBound(dateiliste)+1) 'dateien-array um einen platz erweitern
      ReDim Preserve dirliste(UBound(dateiliste)+1) 'pfade-array um einen platz erweitern
      dateiliste(UBound(dateiliste)) = g 'datei in dateien-array schreiben
      dirliste(UBound(dateiliste)) = subdirliste(x) 'pfad in pfade-array schreiben
       g = Dir("",-1) 'nächste datei
     Loop
   Next
   ReDim subdirliste(0) 'speicherplatz freigeben
End Sub


Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4370
Wohnort: ~/

BeitragVerfasst am: 20.11.2020, 00:22    Titel: Antworten mit Zitat

Zitat:
Das Feilen ist unnötig, einmal ausreichend dimensionieren oder schrittweise erweitern macht keinen messbaren Unterschied.

Das Problem ist halt die Fragmentierung des Speichers. Insofern würde ich eher in größeren Schritten redimensionieren. Solange die Ordner keine riesige Zahl an Unterordnern haben, ist es auch nicht so wild, aber man weiß ja nie, wie das spezielle Dateisystem aussieht. lachen

edit: code-Block durch quote-Block ersetzt
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.


Zuletzt bearbeitet von nemored am 28.11.2020, 20:24, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Terence09



Anmeldungsdatum: 19.11.2020
Beiträge: 4

BeitragVerfasst am: 20.11.2020, 03:01    Titel: Antworten mit Zitat

Danke für die Tipps!

Die Scripte sind sehr umfangreich.
Es würde mir reichen wenn nur eine Ebene abgegrast wird, weil so viele Unterordner sind nicht vorhanden.

Ich würde das Script dann im Hauptordner laufen lassen.
Dann bräuchte ich lediglich einen Code der die enthaltenen Ordner auflistet.

an jedem die .index.htm anhängen und das wär`s!

Also:
Ordner1/index.htm
Ordner2/index.htm
usw...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1050
Wohnort: Ruhrpott

BeitragVerfasst am: 20.11.2020, 18:18    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
Das Problem ist halt die Fragmentierung des Speichers.
Nicht unbedingt. Der Compiler reserviert für ein Array sowieso jedesmal einen größeren Speicherblock. Ich habe es selbst bei umfangreichen (~10000 Elemente) Arrays noch nie erlebt, daß ein elementweise erweitertes Array verschoben worden ist. Der Pointer auf das erste Element war hinterher immer derselbe wie vorher, als das Array nur 1 Element groß war.

Und bei Stringarrays wird im eigentlichen Array immer nur der Stringdescriptor gespeichert, auf den Speicherort des eigentlichen Textes habe ich als Programmierer sowieso keinen Einfluss.

Terence09 hat Folgendes geschrieben:
Die Scripte sind sehr umfangreich.
Das ist doch nicht umfangreich! grinsen Du kannst die Sub einfach in dein Programm kopieren und dann mit den entsprechenden Parametern aufrufen. Aus DirListe() suchst du dir dann die gewünschten Pfade heraus (die Liste ist nach Ebenentiefe geordnet), die anderen lässt du aussen vor. Deshalb stehen Pfade und Dateinamen auch in getrennten Arrays.

Dort, wo im Beispielprogramm die Dateiliste erstellt wird (unter "'liste aller gefundenen dateien mit pfad erstellen") kannst du stattdessen deine eigene Auswerteroutine einfügen.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1785
Wohnort: [JN58JR] DeltaLabs.de

BeitragVerfasst am: 22.11.2020, 01:34    Titel: Antworten mit Zitat

Rekrusive Verzeichnis und Dateiauflistung
Code:
Dim FD() as String
Dim FC as UInteger
Dim DD() as String
Dim DC as UInteger
Dim DX as UInteger
Dim TAttr as Integer
Dim TN as String

'Startverzeichnis
DC = 1
Redim Preserve DD(DC) as String
DD(DC) = "/" 'LINUX
'DD(DC) = "C:\" 'WINDOWS

Do
   DX += 1
   If DX > DC Then Exit Do
   TN = Dir(DD(DX) & "*", -1, @TAttr)
   Do Until TN = ""
      If (TN <> ".") AND (TN <> "..") Then
         If (TAttr AND &H10) <> 0 Then
            DC += 1
            Redim Preserve DD(DC) as String
            DD(DC) = DD(DX) & TN & "/"
         Else
            FC += 1
            Redim Preserve FD(FC) as String
            FD(FC) = DD(DX) & TN
         End If
      End If
      TN = Dir("", -1, @TAttr)
   Loop
   Print DX & "/" & DC
Loop

Print "Verzeichnisse: " & DC
Print "Dateien: " & FC

'DD = Array der Verzeichnisse & Unterverzeichnisse
'DC = Anzahl Elemente im Array
'For X as UInteger = 1 to DC
'...
'Next

'FD = Array der Dateien in allen Verzeichnissen
'FC = Anzahl Elemente im Array
'For X as UInteger = 1 to FC
'...
'Next



EDIT
Variante mit Blockweiser Arrayvergrößerung ...
Code:

'...
Dim DM as UInteger
Dim FM as UInteger
'...
         If (TAttr AND &H10) <> 0 Then
            DC += 1
            If DM < DC Then
               DM = DC + 50
               Redim Preserve DD(DM) as String
            End If
            DD(DC) = DD(DX) & TN & "/"
         Else
            FC += 1
            If FM < FC Then
               FM = FC + 50
               Redim Preserve FD(FM) as String
            End If
            FD(FC) = DD(DX) & TN
         End If
'...



MfG
TPM
_________________
[ WebFBC ][ OPS ][ DeltaLab's ][ ToOFlo ][ BGB-Movie ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
hhr



Anmeldungsdatum: 15.07.2020
Beiträge: 19

BeitragVerfasst am: 22.11.2020, 19:10    Titel: Antworten mit Zitat

Das hier ist zwar etwas langsam, funktioniert aber auch:
Code:
Dim As String Unterordner, Hauptordner = Command(1)

Open Pipe ("DIR/A:D/B/S" & Chr(32,34) & Hauptordner & Chr(34)) For Input As #1
   Do Until Eof(1)
      Line Input #1, Unterordner
      Print Unterordner
   Loop
Close #1

Getkey

Anstelle von Command(1) kann ein Ordnerpfad eingetragen werden.

Wenn man /S entfernt, werden nur die Unterordner des Hauptordners angezeigt.

Anstelle der Print Anweisung kann die eigene Auswertung eingefügt werden.

Zu DIR/A:D/B/S kann in der Eingabeaufforderung help oder help dir eingegeben werden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1785
Wohnort: [JN58JR] DeltaLabs.de

BeitragVerfasst am: 22.11.2020, 20:08    Titel: Antworten mit Zitat

hhr hat Folgendes geschrieben:
...
Code:
'...
Open Pipe ("DIR/A:D/B/S" & Chr(32,34) & Hauptordner & Chr(34)) For
'...



Funzt allerdings NUR auf Windows ...


EDIT
PS: Chr(32,...) verlangsamt den Programmablauf .. ein
Code:
".../B/S "

wäre schneller.

PPS: ein " kann auch mit
Code:
""

erzeugt werden, was das Chr(...) unnötig macht. (-> ist auch schneller)
Code:
Print "  ""TEST""  "



MfG
TPM
_________________
[ WebFBC ][ OPS ][ DeltaLab's ][ ToOFlo ][ BGB-Movie ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Terence09



Anmeldungsdatum: 19.11.2020
Beiträge: 4

BeitragVerfasst am: 27.11.2020, 16:50    Titel: Antworten mit Zitat

Super, Danke für die Scripte,

Wie kann ich die ausgegebenen Texte (Dateiordner und Dateiname"
"Zusammenheften"? Also so dass ich die mit open bearbeiten kann?

Ich würde die Datei dann kopieren, in Dateiname2 ändern, in der Kopie die automatisch die Texte ändern,
und dann wieder in den Ursprungsnamen umbenennen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1785
Wohnort: [JN58JR] DeltaLabs.de

BeitragVerfasst am: 27.11.2020, 20:06    Titel: Antworten mit Zitat

Terence09 hat Folgendes geschrieben:
Ich würde die Datei dann kopieren, in Dateiname2 ändern, in der Kopie die automatisch die Texte ändern,
und dann wieder in den Ursprungsnamen umbenennen.

Warum möchtest du das auf diese Art und Weise machen? Welchen Hintergrund hat das?


MfG
TPM
_________________
[ WebFBC ][ OPS ][ DeltaLab's ][ ToOFlo ][ BGB-Movie ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Terence09



Anmeldungsdatum: 19.11.2020
Beiträge: 4

BeitragVerfasst am: 28.11.2020, 03:41    Titel: Antworten mit Zitat

Hallo ThePuppetMaster

Auf jeder Einzelseite befindet sich ein Google Adsense Code.
Ich muss die EU Cookie Richtlinie umsetzen, und da ich kein CMS benutzt, sondern reine HTML Seiten kann ich kein Cookie Plugin benutzen.
Einfach mit Search und Replace geht auch nicht, weil jeder Adsense Code eine andere ID hat.
Also habe ich ein Programm geschrieben welches die Datei einfach kopiert und den Code aktualisiert.
Das funktioniert jetzt,
ich muss nur noch programmieren dass automatisch jede index.htm in den Unterordnern gefunden wird.

EDIT: Habe jetzt die STRING Funktionen von FREEBASIC durchgelesen, man kann diese ja ganz eifach zusammen "addieren"
Damit müsste ich das Tool fertigstellen koennen, Thanks noch mal an alle!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1785
Wohnort: [JN58JR] DeltaLabs.de

BeitragVerfasst am: 28.11.2020, 22:31    Titel: Antworten mit Zitat

Mir ging es eigentlich um deinen Ablauf ...

1. Datei kopieren
2. kopie ändern
3. Datei "rück"umbenennen

warum eine kopie, und diese dann rück-umbenennen?


MfG
TPM
_________________
[ WebFBC ][ OPS ][ DeltaLab's ][ ToOFlo ][ BGB-Movie ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1050
Wohnort: Ruhrpott

BeitragVerfasst am: 28.11.2020, 23:07    Titel: Antworten mit Zitat

ThePuppetMaster hat Folgendes geschrieben:
warum eine kopie, und diese dann rück-umbenennen?

Richtig, es geht auch wesentlich eleganter. Meine bevorzugte Methode:
Code:
Dim As String arbeitskopie
Open <datei> For Binary Access Read As #1 'datei zum lesen öffnen
arbeitskopie = Input(Lof(1), #1) 'komplette datei in einen string lesen
Close #1
'--------------------------------
'
' dateiinhalt im string "arbeitskopie" mithilfe der stringfunktionen bearbeiten
'
'---------------------------------
Open <datei> For Output As #1 'datei zum schreiben öffnen
Print #1, arbeitskopie; 'neuen inhalt in datei schreiben (semikolon am ende nicht vergessen)
Close #1


Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz