Wie verkette ich mehrere Ausgabezeilen mit einer Zeile?

157

Wenn ich den Befehl ausführe cat file | grep pattern, erhalte ich viele Ausgabezeilen. Wie verketten Sie alle Zeilen in einer Zeile, effektiv jede ersetzt "\n"mit "\" "(Ende mit "durch Leerzeichen)?

cat file | grep pattern | xargs sed s/\n/ /g arbeitet nicht für mich.

T. Webster
quelle
Übrigens: (1) Sie müssen Ihr sedSkript in einfache Anführungszeichen setzen, damit Bash nicht damit herumspielt (da sed s/\n/ /gAufrufe sedmit zwei Argumenten, nämlich s/n/und /g); (2) da Sie möchten, dass die Ausgabe von cat file | grep patterndie Eingabe von sedund nicht die Argumente von ist sed, müssen Sie eliminieren xargs; und (3) hier besteht keine Notwendigkeit cat, da grepein Dateiname als zweites Argument verwendet werden kann. Du hättest es also versuchen sollen grep pattern file | sed 's/\n/ /g'. (In diesem Fall hätte es aus den unter dem obigen Link angegebenen Gründen nicht funktioniert, aber jetzt wissen Sie es für die Zukunft.)
Ruakh
ähnlich wie " stackoverflow.com/questions/2764051/… "
Shervin Emami
Frage mit 68 Stimmen (140.000 Aufrufe), dupliziert mit einem Beitrag, der nur 1 Stimme hat (12.000 Aufrufe)? Das ist nicht richtig.
Kenorb

Antworten:

230

Verwenden Sie tr '\n' ' 'diese Option, um alle Zeilenumbruchzeichen in Leerzeichen zu übersetzen:

$ grep pattern file | tr '\n' ' '

Hinweis: grepLiest Dateien, catverkettet Dateien. Nicht cat file | grep!

Bearbeiten:

trkann nur Einzelzeichenübersetzungen verarbeiten. Sie können awkdas Trennzeichen für Ausgabedatensätze wie folgt ändern:

$ grep pattern file | awk '{print}' ORS='" '

Dies würde sich verwandeln:

one
two 
three

zu:

one" two" three" 
Chris Seymour
quelle
3
Mit diesem Ansatz erhalten Sie am Ende einen unerwünschten Platz.
Sorin
1
Sie müssen echo ""am Ende hinzufügen, um eine neue Zeile vor dem Aufforderungstext hinzuzufügen.
Nexayq
1
Das funktioniert gut, aber ich möchte nicht, dass das Trennzeichen beim allerletzten Eintrag angezeigt wird. Beispiel pro Ihre ", zeigt sich, wie one" two" three", aber ich es , wie zeigen wollen würde one" two" three. Beachten Sie, dass die letzten drei keine Klammern haben. Irgendwelche Ideen?
Oink
2
@oink Sie können die Ergebnisse weiterleiten sed '$s/..$//', um die letzten 2 Zeichen in der letzten Zeile zu löschen.
Chris Seymour
3
Wenn Sie Zeilenumbrüche durch nichts ersetzen möchten, müssen Sie die --deleteOption verwenden, da standardmäßig zwei Argumente erwartet werden. zB tr --delete '\n'.
Elijah Lynn
68

Wenn Sie die Ausgabe an weiterleiten, xargswird jede Ausgabezeile zu einer einzelnen Zeile mit Leerzeichen verknüpft:

grep pattern file | xargs

Oder irgendein Befehl, z. ls | xargs. Die Standardausgabegrenze xargsbeträgt ~ 4096 Zeichen, kann jedoch mit z. xargs -s 8192.

Bluebadge
quelle
| tr '\n' ' 'funktionierte nicht für mich, wenn durch php execFunktion aufgerufen . Es ignorierte tr und gab nur das letzte Match von grep. | xargshat funktioniert.
Adarsha
3
Diese Lösung hat auch den Vorteil, dass sie Leerzeichen von der Eingabe "frisst". +1
Rene
55

echoEntfernen Sie in Bash ohne Anführungszeichen Wagenrückläufe, Tabulatoren und mehrere Leerzeichen

echo $(cat file)
user1699917
quelle
8
Die hier stark unterschätzte Antwort ist wirklich einfach und funktioniert wie ein Zauber, auch mit einem nachgestellten Zeilenumbruch.
Dangercrow
Dies ist besonders ordentlich, wenn Sie verwendenIFS="$(printf '\n\t')"
aggsol
5
Oder einfach echo $(<file)... Echo zu verwenden ist nicht nur ordentlicher als zu verwenden tr '\n' ' ', sondern auch besser (denken Sie an \r\nZeilenenden). @aggsol können Sie nur sagenIFS=$'\n\t'
Normadize
Wie wäre es ohne Platz?
DimiDak
22

Dies könnte sein, was Sie wollen

cat file | grep pattern | paste -sd' '

Ich bin mir nicht sicher, was es bedeutet, vielleicht das?

cat file | grep pattern | paste -sd'~' | sed -e 's/~/" "/g'

(dies setzt voraus, dass ~dies in nicht vorkommt file)

sehe sehen
quelle
2
@Stephan gab es keine Notwendigkeit anzunehmen, dass dies cat filetatsächlich sein wird cat, oder sogar eine Datei. (Ich habe diesen Teil einfach unverändert gelassen, da er für die Frage irrelevant war)
sehe
5

Dies ist ein Beispiel, das eine durch Kommas getrennte Ausgabe erzeugt. Sie können das Komma durch ein beliebiges Trennzeichen ersetzen.

cat <<EOD | xargs | sed 's/ /,/g'
> 1
> 2
> 3
> 4
> 5
> EOD

produziert:

1,2,3,4,5
Richard Gomes
quelle
3

Hier ist die Methode mit dem exEditor (Teil von Vim ):

  • J oin alle Linien und p rint auf die Standardausgabe:

    $ ex +%j +%p -scq! file
  • J oin alle Linien in-place (in der Datei):

    $ ex +%j -scwq file

    Hinweis: Dadurch werden alle Zeilen in der Datei selbst verkettet!

Kenorb
quelle
2

Die schnellsten und einfachsten Möglichkeiten, dieses Problem zu lösen:

Wenn wir das neue Zeilenzeichen \n durch das Leerzeichen ersetzen möchten :

xargs < file

xargshat eigene Grenzen für die Anzahl der Zeichen pro Zeile und die Anzahl aller Zeichen zusammen, aber wir können sie erhöhen. Details finden Sie mit diesem Befehl: xargs --show-limitsund natürlich im Handbuch:man xargs

Wenn wir ein Zeichen durch ein anderes ersetzen möchten, genau ein Zeichen :

tr '\n' ' ' < file

Wenn wir ein Zeichen durch viele Zeichen ersetzen möchten :

tr '\n' '~' < file | sed s/~/many_characters/g

Zuerst ersetzen wir die Zeilenumbruchzeichen \nfür Tildes ~(oder wählen ein anderes eindeutiges Zeichen, das nicht im Text enthalten ist), und dann ersetzen wir die Tildezeichen durch andere Zeichen ( many_characters) und tun dies für jede Tilde (Flagge g).

simhumileco
quelle
0

Der wahrscheinlich beste Weg, dies zu tun, ist die Verwendung des Tools 'awk', mit dem die Ausgabe in einer Zeile generiert wird

$ awk ' /pattern/ {print}' ORS=' ' /path/to/file

Alle Zeilen werden mit einem Leerzeichen in einer Zeile zusammengeführt

Vladimir Yahello
quelle
Sie brauchen nicht, {print}da es die Standardaktion von awk ist.
stark
0

Unter Red Hat Linux verwende ich nur Echo:

echo $ (cat / some / file / name)

Dies gibt mir alle Datensätze einer Datei in nur einer Zeile.

user13498546
quelle
1
Dies war bereits eine Antwort im Jahr 2015. Sie duplizieren diese Antwort nur . Bitte lesen Sie die Antworten, bevor Sie Ihre eigenen veröffentlichen, insbesondere wenn die Frage 7 Jahre alt ist und bereits 8 Antworten vorliegen.
Mickael B.