Skript zum Löschen von Textdateien

Skript zum Löschen von Textdateien

Ich habe versucht, ein Skript zu erstellen, das nach allen ASCII-Textdateien im angegebenen Verzeichnis sucht und anschließend den Pfad jeder Datei in eine Textdatei schreibt. Danach soll es den Kopf jeder Datei einzeln anzeigen und fragen, ob Sie die Datei löschen möchten. Wenn Sie „Ja“ sagen, wird diese Datei entfernt, wenn Sie etwas anderes sagen, wird Ihnen einfach die nächste Datei angezeigt usw., bis Sie jede Datei überprüft haben. Das Ergebnis lautet also:

#!/bin/bash
echo "Give directory to search for ASCII text files"
read direct
find $direct -type f -exec file {} + | grep ASCII > ztextz
sed "s/ .*//" ztextz > ztextz1
sed "s/://g" ztextz1 > ztextz2
#until here everything works fine
#it creates the file that contains paths of all ASCII text files in the directory given by you
#After that it is a mess..it needs to check the head of every file one by one
#and let me decide if I want to delete it or not
files=ztextz2
while IFS= read -r name;
do
head "$name";

echo "Do you want to delete this file?"
read want
case $want in
YES)
rm $name;;
Yes)
rm $name;;
yes)

rm $name;;
Y)
rm $name;;
y)
rm $name;;
esac
done < "$files"

Als Ausgabe soll ich also 10 Zeilen aus der ersten Textdatei in meinem Verzeichnis sehen und gefragt werden, ob ich diese Datei entfernen möchte. Wenn ich mit „Ja“ antworte, soll diese Datei entfernt werden und mir die 10 Zeilen aus der nächsten Datei usw. angezeigt werden.

Die Ausgabe, die ich jetzt erhalte, besteht aus den ersten 10 Zeilen von 2 Dateien (ich habe 4 Dateien in meinem Verzeichnis) und der Frage „Möchten Sie diese Datei löschen?“ und dann bricht das Skript ab.

Scheint, als ob es nicht wie erwartet funktioniert. Kann mir bitte jemand erklären, wo mein Fehler liegt?


OK, da mein Ruf nicht ausreicht, um selbst zu antworten, schreibe ich es hier.


Ja, also ich bin bei meinem alten Skript geblieben, bei dem ich Probleme damit hatte, zwei $$ zusammenzusetzen, also $$numb, und sie durch ${!numb} ersetzt habe. Dann hat es angefangen zu funktionieren... also kann ich jetzt mit diesem Skript meine Verzeichnisse von den Textdateien säubern, die ich nicht brauche =)

   #!/bin/bash
echo "Give directory to search for ASCII text files"
read direct
find $direct -type f -exec file {} + | grep ASCII > ztextz
sed "s/ .*//" ztextz > ztextz1
sed "s/://g" ztextz1 > ztextz2
set `less ztextz2`
numb=$#
rm ztextz*
while [ $numb -gt 0 ]
do head ${!numb}
echo "Do you want to delete ${!numb} file?"
read want
case $want in
yes)
rm ${!numb}
echo "File is removed"
sleep 1;;
Yes)
rm ${!numb}
echo "File is removed"
sleep 1;;
Y)
rm ${!numb}
echo "File is removed"
sleep 1;;
y)
rm ${!numb}
echo "File is removed"
sleep 1;;
YES)
rm ${!numb}
echo "File is removed"
sleep 1;;
esac
numb=$[$numb-1]
done

PS. damit es schneller geht, entfernen sleep 1=)

Antwort1

Das Problem ist, dass Sie die Datei lesen mitzweiInstanzen von read- eine zum Lesen des Dateinamens, die andere zum Abrufen der Antwort. Das readWarten auf die Antwort frisst also jeden zweiten Dateinamen und Sie sollten hoffen, dass die Dateiliste nicht so aussieht:

some_throuwaway_stuff
foo
very_important_file.txt
Yes
some_throuwaway_stuff
foo

Ihr Skript sollte wahrscheinlich ungefähr so ​​aussehen:

#!/bin/bash
echo "Give directory to search for ASCII text files"
read direct
exec 3<&0
find "$direct" -type f |
while IFS= read -r name; do
    echo "========================================"
    if file "$name" | grep ASCII; then
        echo "----------------------------------------"
        head "$name";
        echo "----------------------------------------"
        echo "Do you want to delete this file?"
        read -u 3 want
        case $want in
            YES|Yes|yes|Y|y)
                rm "$name"
                ;;
            *)
                ;;
        esac
    fi
done

Beachten Sie die Umleitung , die regelmäßig zum Dateideskriptor 3 exec 3<&0führt , der dann im Zyklus auf eine Antwort des Benutzers überprüft wird.stdin

Das heißt, rm -ies ist wahrscheinlich die bessere Option.

Antwort2

Sie können Ihren Block ersetzen

while [ $numb -gt 0 ]
    do head ${!numb}
    echo "Do you want to delete ${!numb} file?"
    read want
    case $want in
        yes)
            rm ${!numb}
            echo "File is removed"
            sleep 1;;
        Yes)
            rm ${!numb}
            echo "File is removed"
            sleep 1;;
        Y)
            rm ${!numb}
            echo "File is removed"
            sleep 1;;
        y)
            rm ${!numb}
            echo "File is removed"
            sleep 1;;
        YES)
            rm ${!numb}
            echo "File is removed"
            sleep 1;;
    esac
    numb=$[$numb-1]
done

von

while [ $numb -gt 0 ]
do
    head ${!numb}
    rm -i ${!numb}
    numb=$[$numb-1]
done

verwandte Informationen