Doppelte Dateien löschen.

johnix

johnix

Jungspund
Hallo, ich habe versucht ein Shell Script zu schreiben, das mir mit Hilfe von fdupes; doppelte Dateien löscht.
Ich benutze die Bash und Ubuntu 10.04

Code:
#!/bin/bash

# Info
# DoppelteDateienLoeschen ddl.sh
# X.inh wurde von fdupes erzeugt
# fdupes . > /root/X.inh
# und beinhaltet eine Auflistung doppelter Dateien in Blocks,
# welche durch je eine LEERZEILE, getrennt sind.
# Die erste und zweite Zeile, eines Blockes, sollte demnach einen Dateinamen enthalten.
# ./datei.xxx
# Die LETZTE in einem Block enthaltene Datei, soll erhalten bleiben, alle anderen werden geloescht.
# Die letzte Zeile von X.inh, muss eine Leerzeile sein.
# Trotzdem das Script nach /usr/bin gesetzt wurde und chmod u+x, angewendet wurde; laesst es sich nur mit "bash ddl.sh"; starten.
# Nach /usr/local/bin setzen.
# Es muss, aus dem Verzeichniss aufgerufen werden, aus dem die X.inh, mit fdupes erzeugt wurde.

i=0
b=1                                             # boolean:true
AFILE=/root/X.inh
while read ZEILE
do                  # durchlaeuft die Datei Zeile fuer Zeile.
{
  echo $Zeile
  if [ "${ZEILE}" != "" -a "$b" -eq "0" ]   # wird ausser beim ersten Durchlauf, nur noch durchlaufen, im Block.
    then                                        # Zeile2 nicht leer, Zeile1 loeschen b=true
    {
    exec rm "$ZEILE1"                           # If Abfrage aus logischen Gruenden, vor die jetzt folgende if Abfrage gesetzt.
    echo "$ZEILE1" "gelöscht."
    ZEILE1="${ZEILE}"
    echo "$ZEILE1"
    }
  fi

  if [ "${ZEILE}" != "" -a "$b" -eq "1" ]   # wird nur ein mal durchlaufen, beim ersten einzulesenden String, pro Block.
    then                                        # Zeile nicht leer und b=false
    {
    ZEILE1="${ZEILE}"
    b=0
    echo "$ZEILE1" $b
    }
  fi

  if [ "${ZEILE}" = "" -a "$b" -eq "1" ]    # wird durchlaufen wenn ZEILE leer ist.
    then                                        # Fehler. b=false
    {
    echo "FEHLER; ZEILE leer und b=1"           # If Abfrage aus logischen Gruenden, vor die jetzt folgende if Abfrage gesetzt.
    exit 1
    }
  fi

  if [ "${ZEILE}" = "" -a "$b" -eq "0" ]    # wird durchlaufen wenn ZEILE leer ist.
    then                                        # b=true
    {
    echo "$ZEILE" "Zeile leer"
    b=1
    echo $b
     }
 fi

  i=$(($i + 1))      # i++
  echo $i 
}
done < $AFILE                                           # Ende while. Uebergabe der Datei.
exit 0

Ich stricke da schon Jahre daran herum. Die erste Datei wird beim jetzigen Script, gelöscht. Leider aber scheint echo keine Wirkung zu haben. Ich bin Anfänger und das Script sollte mir helfen, die Bash zu verstehen, bzw, den Umgang damit. Vielleicht mache ich ja nur eine Kleinigkeit falsch.
 
Zuletzt bearbeitet:
Code:
#!/bin/bash

file="/root/X.inh"
isLineOne=true

lineOne=""
lineTwo=""

# lies Datei Zeile fuer Zeile ein
while read line
do
  # wenn wir auf der ersten zeile sind,
  # lies zeile ein, und geh zur naechsten zeile
  if $isLineOne ; then 
    lineOne=$line
    isLineOne=false
    continue
  # der uebliche fall
  # wir haben bereits eine zeile, und lesen die zweite ein
  else 
    lineTwo=$line
  fi

  # sonderfall leerzeile
  # wenn zeile 1 eine leerzeile ist, dann haben wir einen neuen block
  # brauchen wir nichts loeschen, weiter mit der naechsten zeile
  if [[ $lineOne = "" ]]; then 
    lineOne=$lineTwo
    continue
  fi

  # wenn die naechste Zeile nicht leer ist haben wir ein duplikat
  # also weg damit
  if [[ $lineTwo != "" ]]; then
    echo "removing file ${lineOne}"
    # rm ${lineOne}
  # wenn doch, dann sind wir an der letzten datei im block
  # die wollen wir behalten
  else
    echo "keeping file ${lineOne}"
  fi

  # alte zeile zwei wird neue zeile eins
  # weiter mit der naechsten zeile
  lineOne=$lineTwo
done < $file

exit 0

das sollte tun (auch mit mehr als einem duplikat), noch ein paar Anmerkungen:
  • "exec rm" ist unnoetig, wenn nicht sogar ein Fehler
  • die '{', '}' in den if's auch, zumindest ist eine Subshell dort fehl am Platz
  • die Bash hat booleans (false, true), kein Grund fuer C-Style 0/1
  • die '[' und ']' fuer test(1) sollten afaik als '[[' und ']]' geschrieben werden (geht aber auch so)
 
Hi,

  • die '[' und ']' fuer test(1) sollten afaik als '[[' und ']]' geschrieben werden (geht aber auch so)
Jain, '[' und '[[' sind unterschiedliche Operatoren und nicht zu verwechseln. Letzterer ist neuer und weniger portabel, unterstuetzt aber einfachere Syntax.

Wobei ich mir auch nicht ganz sicher bin ob sie fuer neuere Bash Versionen vielleicht equivalent sind. Inzwischen laesst die Bash IMHO auch fuer '[' Dinge zu, die frueher nicht moeglich waren.

mfg,
bytepool
 
Zu Erst einmal Danke.-)
Ich probiere das morgen mal aus.
Ich hatte mit und ohne ´{´ und was weiss ich für Versionen des Scriptes erstellt.
Hatte aber nie geklappt. Ich glaube jetzt zu wissen, woran es lag.
Dein Script erscheint mir viel einfacher.
Ich habe versucht, mich so weit als möglich, an den Beschreibungen, für die Bash zu orientieren.
Wenn ´[´ schlechter Stil ist, nehme ich zukünftig nur mehr ´[[´.
Bei Booleans, wusste ich nicht, wie anwenden, aber jetzt bin ich auch da schlauer.
Ich habe übrigens, auch sehr lange, nichts mehr programmiert gehabt

Bis morgen abend habe ich das ausprobiert und melde mich dann wieder.
Vielen Dank nochmal, für Script und Anmerkung.

Leider habe ich nicht viel Zeit im Moment, komme morgen ins Krankenhaus zur Untersuchung.
Habe das Script getestet und es funktioniert talürnich auf Anhieb. Ich werde mir da aber noch ein Testverzeichnis einrichten und das mal vollständig testen/durcharbeiten. Ich will ja was lernen.

Also nochmals 1000 mal Danke.-)
 
Zuletzt bearbeitet:

Ähnliche Themen

If-Abfrage kommt nicht positiv zurück, obwohl Kriterium erfüllt

Switche abfragen über Script

Hilfe für ein shell script

script sshpass

Verschlüsseltes Backup-Script mit rsync

Zurück
Oben