GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux:Wie verwende ich eine Datei gleichzeitig als Ein- und Ausgabe?

Lösung 1:

echo "$(uniq .bash_history)" > .bash_history

sollte das gewünschte Ergebnis haben. Die Subshell wird vor .bash_history ausgeführt ist zum Schreiben geöffnet. Wie in Phil Ps Antwort erklärt, bis zum Zeitpunkt .bash_history im ursprünglichen Befehl gelesen wird, wurde er bereits um die > abgeschnitten Betreiber.

Lösung 2:

Ich empfehle die Verwendung von sponge von moreutils. Aus der Manpage:

DESCRIPTION
  sponge  reads  standard  input  and writes it out to the specified file. Unlike
  a shell redirect, sponge soaks up all its input before opening the output file.
  This allows for constructing pipelines that read from and write to the same 
  file.

Um dies auf Ihr Problem anzuwenden, versuchen Sie:

uniq .bash_history | sponge .bash_history

Lösung 3:

Das Problem besteht darin, dass Ihre Shell die Befehlspipeline einrichtet, bevor die Befehle ausgeführt werden. Es geht nicht um "Eingabe und Ausgabe", sondern darum, dass der Inhalt der Datei schon weg ist, bevor uniq überhaupt läuft. Es geht ungefähr so:

  1. Die Shell öffnet den > Ausgabedatei zum Schreiben, Abschneiden
  2. Die Shell richtet sich so ein, dass der Dateideskriptor 1 (für stdout) für diese Ausgabe verwendet wird
  3. Die Shell führt uniq aus, vielleicht so etwas wie execlp("uniq", "uniq", ".bash_history", NULL)
  4. uniq läuft, öffnet .bash_history und findet dort nichts

Es gibt verschiedene Lösungen, einschließlich der Bearbeitung vor Ort und der Verwendung temporärer Dateien, die andere erwähnen, aber der Schlüssel liegt darin, das Problem zu verstehen, was tatsächlich schief läuft und warum.

Lösung 4:

Ein weiterer Trick, um dies zu tun, ohne sponge zu verwenden , ist der folgende Befehl:

{ rm .bash_history && uniq > .bash_history; } < .bash_history

Dies ist einer der Cheats, die in dem hervorragenden Artikel „In-Place“-Bearbeitung von Dateien auf backreference.org beschrieben werden.

Es öffnet im Grunde die Datei zum Lesen und "entfernt" sie dann. Es wird jedoch nicht wirklich entfernt:Es gibt einen offenen Dateideskriptor, der darauf zeigt, und solange dieser geöffnet bleibt, ist die Datei immer noch vorhanden. Dann erstellt es eine neue Datei mit demselben Namen und schreibt die eindeutigen Zeilen hinein.

Nachteil dieser Lösung:Wenn uniq aus irgendeinem Grund fehlschlägt, wird Ihr Verlauf gelöscht.

Lösung 5:

Schwamm von moreutils verwenden

uniq .bash_history | sponge .bash_history

Linux
  1. So verwenden Sie den Tar-Befehl unter Linux

  2. Verwendung des Linux-Touch-Befehls + Beispiele

  3. So erstellen Sie einen Alias ​​und verwenden den Alias-Befehl in Linux

  4. So leiten Sie die Ausgabe in eine Datei und Stdout in Linux um

  5. Wie kopiert man eine Datei und erstellt gleichzeitig die Zielverzeichnisse?

Linux-Dateibefehl:Was macht er und wie wird er verwendet?

So verwenden Sie Sudo und die Sudoers-Datei

So verwenden Sie den Linux-Befehl ftp zum Hoch- und Herunterladen von Dateien auf der Shell

Linux-Hostdatei:Wie wird sie bearbeitet und verwendet?

So erstellen und verwenden Sie eine Auslagerungsdatei unter Linux

Wie verwende ich den Gzip-Befehl unter Linux?