Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Terence09
Anmeldungsdatum: 19.11.2020 Beiträge: 4
|
Verfasst am: 19.11.2020, 16:24 Titel: Dateien in Verzeichnissen finden |
|
|
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 |
|
|
hhr
Anmeldungsdatum: 15.07.2020 Beiträge: 88
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 19.11.2020, 20:23 Titel: |
|
|
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 |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 20.11.2020, 00:42 Titel: |
|
|
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 ). 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 |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 20.11.2020, 01:22 Titel: |
|
|
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.
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, 21:24, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Terence09
Anmeldungsdatum: 19.11.2020 Beiträge: 4
|
Verfasst am: 20.11.2020, 04:01 Titel: |
|
|
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 |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 20.11.2020, 19:18 Titel: |
|
|
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! 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 |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 22.11.2020, 02:34 Titel: |
|
|
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 ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
hhr
Anmeldungsdatum: 15.07.2020 Beiträge: 88
|
Verfasst am: 22.11.2020, 20:10 Titel: |
|
|
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 |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 22.11.2020, 21:08 Titel: |
|
|
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
wäre schneller.
PPS: ein " kann auch mit
erzeugt werden, was das Chr(...) unnötig macht. (-> ist auch schneller)
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
Terence09
Anmeldungsdatum: 19.11.2020 Beiträge: 4
|
Verfasst am: 27.11.2020, 17:50 Titel: |
|
|
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 |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 27.11.2020, 21:06 Titel: |
|
|
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 ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
Terence09
Anmeldungsdatum: 19.11.2020 Beiträge: 4
|
Verfasst am: 28.11.2020, 04:41 Titel: |
|
|
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 |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 28.11.2020, 23:31 Titel: |
|
|
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 ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 29.11.2020, 00:07 Titel: |
|
|
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 |
|
|
|