#!/bin/bash set -o nounset set -o errexit set -o pipefail declare -r SCRIPT_DIR="$( cd "$( dirname "$" )" && pwd )" declare -r FILES_DIR=$ while read -r ONE_PATH do for ONE_FILE in $(find "$FILES_DIR" -maxdepth 1 -type f -print) do if [[ "$ONE_FILE" == *".swp" ]] || [[ "$ONE_FILE" == *"common.txt" ]]; then continue fi sed -i '\|^'"$ONE_PATH"'$|d' "$ONE_FILE" done echo "Done removing $ONE_PATH" done < "$SCRIPT_DIR"/../common.txt exit 0
sed: Löschen einer Liste von Pfaden aus einem Dateisatz
Ich habe eine Datei namens common.txt, die eine Liste absoluter Pfade enthält. Zum Beispiel:
/etc /etc/group /var/log/syslog
Ich habe auch eine Reihe von Dateien <hostname> .txt, die auch eine Liste absoluter Pfade enthalten. Hier ist ein Beispiel (nennen Sie es host1.txt ):
/root/.bashrc /var/log/syslog /etc/hosts /bin/true /etc /sbin/rtmon /etc/group
Ich möchte jeden Pfad, der in common.txt angezeigt wird, aus jeder Datei im Dateisatz <Dateiname> .txt entfernen . Die Beispieldatei host1.txt würde also zu:
/root/.bashrc /etc/hosts /bin/true /sbin/rtmon
Ich habe dazu das folgende Bash-Skript geschrieben:
#!/bin/bash set -o nounset set -o errexit set -o pipefail while read -r ONE_PATH do for ONE_FILE in host1.txt host2.txt host3.txt do sed -i '\:'"$ONE_PATH"':d' "$ONE_FILE" done done < common.txt
Ich habe Schwierigkeiten, den sed-Befehl richtig zu machen. Was oben gezeigt wird, führt dazu, dass alle Dateien bearbeitet werden, wenn sie leer sind.
Wie kann ich das beheben, um mein Ziel zu erreichen?
3 Antworten auf die Frage
Darf ich eine Lösung vorschlagen, die sed nicht verwendet?
sort common.txt > common.txt.sorted for f in host1.txt host2.txt host3.txt ; do sort $f > $f.sorted diff common.txt.sorted $f.sorted | egrep '^>' | sed -e 's/^> //' > $f.output rm $f.sorted done
Art sortiert Listen in alphabetischer Reihenfolge. diff findet die Unterschiede zwischen einer Datei und common.txt . egrep wählt Zeilen aus, die mit beginnen . Dies>
sind Zeilen in host1.txt.sorted, jedoch nicht in common.txt.sorted . Zum Schluss entfernt sed das führende >
(durch ein Leerzeichen gefolgtes Leerzeichen), das von diff hinzugefügt wird .
Die Ausgabeliste wird auch in alphabetischer Reihenfolge angezeigt.
Zuerst sollte die Eingabe in umgekehrter Reihenfolge sein. Es ist sinnlos, / etc zu entfernen und dann nach / etc / group zu suchen. Dann überprüfen wir, ob in die Datei geschrieben werden kann (falls nicht übersprungen). Dann sollte ONE_PATH entkommen werden und Sed kann dann seine Arbeit verrichten.
sort -r common.txt \ | while read -r ONE_PATH do for ONE_FILE in host1.txt host2.txt host3.txt do if [ -w "$ONE_FILE" ] then # sed -i '\:'"$ONE_PATH"':d' "$ONE_FILE" ONE_PATH_ESC=$(echo "$ONE_PATH" | sed "s!/!\\\/!g") sed -i 's/^'"$ONE_PATH_ESC"'//' "$ONE_FILE" fi done done
Mit den bereitgestellten Testdaten erhalten Sie:
$ pr -n host1.txt 1 /root/.bashrc 2 3 /hosts 4 /bin/true 5 6 /sbin/rtmon 7
Es gibt 3 leere Zeilen.
Verwandte Probleme
-
9
Was ist der Unterschied zwischen den Befehlen "su -s" und "sudo -s"?
-
4
Gutes freies Ubuntu Server-VMWare-Image benötigt
-
4
Was sind die Unterschiede zwischen den großen Linux-Distributionen? Werde ich es merken
-
2
Begrenzung der CPU-Auslastung für Flash in Firefox?
-
2
Wie kann ich mein Mikrofon unter Debian GNOME zum Laufen bringen?
-
2
Conky-Setups - Beispiele / Ideen?
-
3
Was sind die Unterschiede zwischen Linux Window Managern?
-
2
ThunderBird / Lichtsynchronisation mit SE k770i
-
4
Linux-Dateisystem
-
6
Vollbild-Flash langsam in KDE 4