Holen Sie sich bestimmte Inhalte einer Datei

9

Ich weiß also, dass es für dieses Problem Tools gibt, weil ich davon gehört habe, aber ich weiß nicht, was sie sind.

Ich möchte so etwas wie alle Daten außer den Benutzernamen in / etc / passwd herausfiltern.

Zum Beispiel möchte ich Benutzer1, Benutzer2 und Benutzer3 aus der folgenden Datei holen. In diesem Fall könnte die Logik "Text bis zum ersten ':' in jeder Zeile der Datei abrufen" lauten.

user1:x:1:4
user2:x:2:5
user3:x:3:6

Die Ausgabe wäre:

user1
user2
user3
Mouche
quelle

Antworten:

19

cutexistiert genau zu diesem Zweck. Das -dFlag gibt das Trennzeichen an und -fgibt an, welche Felder ausgegeben werden sollen:

cut -d: -f1 /etc/passwd

Das Argument zu -fkann so etwas wie 1,3das erste und dritte Feld oder 1-3die ersten drei sein; Es gibt auch -bund -cFlags zum Lesen von Bytes und Zeichen anstelle von Feldern. Wenn Sie etwas flexibleres benötigen, reicht dies im Allgemeinen aus awk(siehe Matthews Antwort ).

Michael Mrozek
quelle
13

Jedes Mal, wenn Sie Daten aus einer tabellarischen Eingabe extrahieren möchten, sollten Sie awk berücksichtigen . Es ist auf praktisch jedem Unix-System verfügbar, daher ist es eine gute Angewohnheit:

awk -F':' '{print $1}' /etc/passwd 
  • -F':': definiert ":" als Spaltenbegrenzer.
  • '{}': Führen Sie diese Anweisung für jede Zeile aus.
  • print $1: Drucken Sie die erste Spalte auf dem Bildschirm.
Matthew Brannigan
quelle
3
Zufällige Anmerkung: awkNimmt einen Dateinamen, so dass Sie die Pipe überspringen und einfach tun könnenawk -F: '{print $1}' /etc/passwd
Michael Mrozek
Ich scheine immer zu vergessen, dass awk einen Dateinamen annimmt, ich scheine ihn immer in einer Pipeline zu verwenden ... so etwas wie sed | awk etc ...
Matthew Brannigan
Fast alles, was mit Dateien funktioniert, hat einen Dateinamen ( trund atsind einige Beispiele für die wenigen Dinge, die dies nicht tun).
Bis auf weiteres angehalten.
3

Hier ist ein Perl-Einzeiler:

perl -F/:/ -lane 'print $F[0]' /etc/passwd
Zaid
quelle
1

Unter Perl und Awk gibt es ein drittes Tool für solche Jobs, das sed:

sed 's/:.*//' FILE 

Dies ist der Ersetzungsbefehl: Ersetzen durch Doppelpunkt:, gefolgt von einem Punkt, der ein Joker für Zeichen jeglicher Art, beliebiger Anzahl (*) und nichts ist.

Es ist 's (ubstitute) / FROM / TO /', wobei TO leer ist, was bedeutet, dass 'alles aus dem ersten (da sed standardmäßig gierig ist) Doppelpunkt (bis zum Zeilenende, da sed gut mit ganzen Zeilen funktioniert) gelöscht wird.

Natürlich cutist das auch ein guter Befehl, aber ich würde sagen, aus einer anderen Familie.

Benutzer unbekannt
quelle
1

In Ihrem Beispiel sind alle 3 Namen gleich lang. In solchen Fällen - was passieren kann, aber mit / etc / passwd nicht so wahrscheinlich - können Sie auch colrm verwenden:

echo "user1:x:1:4
> user2:x:2:5
> user3:x:3:6" | colrm 6
user1
user2
user3

oder natürlich

cat FILE | colrm 6 

(Ein seltener Fall, in dem useless use of catdies nicht zutrifft, da Sie eine DATEI nicht als Parameter übergeben können.)

Benutzer unbekannt
quelle
catist dort noch nutzlos : colrm 6 < FILE.
Manatwork
Nun ja, aber nicht so nutzlos, wie beim Anrufen cat foo | grep bar.
Benutzer unbekannt
1

Der Vollständigkeit halber sind keine externen Befehle erforderlich, die Shell (Bourne-Shell oder kompatibel) kann sie alleine verarbeiten:

while IFS=':' read -r needed garbage; do echo "$needed"; done < input_file

Natürlich ist dies wahrscheinlich die langsamste aller möglichen Lösungen. Wählen Sie daher für große Dateien eine andere aus.

Mann bei der Arbeit
quelle