it-swarm.com.de

Wie füge ich mehrere Dateinamenzeilen mit einem benutzerdefinierten Trennzeichen zusammen?

Ich möchte das Ergebnis von ls -1 In einer Zeile zusammenfassen und mit dem abgrenzen, was ich will.

Gibt es Standard-Linux-Befehle, mit denen ich dies erreichen kann?

379
JavaRocky

Ähnlich wie bei der allerersten Option, jedoch ohne nachfolgendes Trennzeichen

ls -1 | paste -sd "," -
586
Artem

EDIT : Einfach "ls -m" Wenn Ihr Trennzeichen ein Komma sein soll

Ah, die Kraft und Einfachheit!

ls -1 | tr '\n' ','

Ändern Sie das Komma "," nach Belieben. Beachten Sie, dass dies ein "nachstehendes Komma" enthält.

353
zaf

Dies ersetzt das letzte Komma durch eine neue Zeile:

ls -1 | tr '\n' ',' | sed 's/,$/\n/'

ls -m enthält Zeilenumbrüche am bildschirmbreiten Zeichen (z. B. 80.).

Meistens Bash (nur ls ist extern):

saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS

Verwenden von readarray (aka mapfile) in Bash 4:

readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS

Danke an gniourf_gniourf für die Vorschläge.

24

Ich finde das großartig

ls -1 | awk 'ORS=","'

ORS ist das "Trennzeichen für Ausgabedatensätze", daher werden Ihre Zeilen jetzt mit einem Komma verbunden.

19
majkinetor

Die Kombination von Einstellung IFS und Verwendung von "$*" kann machen was du willst. Ich benutze eine Subshell, damit ich die $ IFS dieser Shell nicht störe

(set -- *; IFS=,; echo "$*")

Um die Ausgabe zu erfassen,

output=$(set -- *; IFS=,; echo "$*")
14
glenn jackman

Parsing ls im Allgemeinen wird nicht empfohlen , daher ist es eine Alternative, find zu verwenden, zum Beispiel:

find . -type f -print0 | tr '\0' ','

Oder mit find und paste:

find . -type f | paste -d, -s

Wenn Sie generell mehrere Zeilen verbinden möchten (nicht im Zusammenhang mit dem Dateisystem), überprüfen Sie Folgendes: Kompakter und portabler Join in der Unix-Befehlszeile .

13
kenorb

Das Rad nicht neu erfinden.

ls -m

Es macht genau das.

9

Dieser Befehl ist für die Perl-Fans:

ls -1 | Perl -l40pe0

Hier ist 40 der Oktal-ASCII-Code für den Raum.

-p verarbeitet Zeile für Zeile und druckt

-l wird dafür sorgen, dass das abschließende\n durch das von uns angegebene ASCII-Zeichen ersetzt wird.

-e soll Perl darüber informieren, dass die Befehlszeile ausgeführt wird.

0 bedeutet, dass tatsächlich kein Befehl ausgeführt werden muss.

Perl -e0 ist dasselbe wie Perl -e ''

7

schlagen Sie einfach

mystring=$(printf "%s|" *)
echo ${mystring%|}
7
ghostdog74

Um mögliche Newline-Verwirrungen für tr zu vermeiden, könnten wir das -b-Flag zu ls hinzufügen:

ls -1b | tr '\n' ';'
6
yabt

Es sieht so aus, als ob die Antworten bereits existieren.

Falls Sie es wollen a, b, c Format, benutze ls -m ( Tulains Córdovas Antwort )

Oder wenn Sie wollen a b c Format, benutze ls | xargs (vereinfachte Version von Chris Js Antwort )

Oder wenn Sie ein anderes Trennzeichen wie |, verwenden ls | paste -sd'|' (Anwendung von Artems Antwort )

4
plhn
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

Erläuterung:

-e - bezeichnet einen auszuführenden Befehl
:a - ist ein Label
/$/N - Definiert den Umfang der Übereinstimmung für die aktuelle und die (N) ext-Zeile
s/\n/\\n/; - Ersetzt alle EOL durch \n
ta; - gehe zu Label a, wenn die Übereinstimmung erfolgreich ist

Entnommen aus meinem Blog .

3
Anand Rajasekar

Wenn Ihre Version von xargs das Flag -d unterstützt, sollte dies funktionieren

ls  | xargs -d, -L 1 echo

-d ist das Trennzeichen

Wenn Sie -d nicht haben, können Sie Folgendes versuchen

ls | xargs -I {} echo {}, | xargs echo

Mit den ersten xargs können Sie Ihr Trennzeichen angeben, das in diesem Beispiel ein Komma ist.

3
Chris J

Der sed Weg,

sed -e ':a; N; $!ba; s/\n/,/g'
  # :a         # label called 'a'
  # N          # append next line into Pattern Space (see info sed)
  # $!ba       # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop
  # s/\n/,/g   # any substitution you want

Hinweis :

Dies ist von linearer Komplexität und wird nur einmal ersetzt, nachdem alle Zeilen in den Pattern Space von sed eingefügt wurden.

@ AnandRajasekas Antwort und einige andere ähnliche Antworten, wie hier , sind O (n²), weil sed jedes Mal, wenn eine neue Zeile an das Pattern angehängt wird, einen Ersatz benötigt Platz.

Vergleichen,

seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
  # linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
  # quadratic, hung
3
zhazha

Sie können verwenden:

ls -1 | Perl -pe 's/\n$/some_delimiter/'
2
codaddict

ls erzeugt eine Spaltenausgabe, wenn es an eine Pipe angeschlossen wird, so dass -1 redundant ist.

Hier ist eine andere Perl-Antwort, die die eingebaute Funktion join verwendet, die keinen abschließenden Begrenzer hinterlässt:

ls | Perl -F'\n' -0777 -anE 'say join ",", @F'

Das obskure -0777 Veranlasst Perl, alle Eingaben zu lesen, bevor das Programm ausgeführt wird.

sed alternative, die keinen abschließenden Begrenzer hinterlässt

ls | sed '$!s/$/,/' | tr -d '\n'
2
Thor

Zusätzlich zu Majkinetors Antwort können Sie hier das abschließende Trennzeichen entfernen (da ich unter seiner Antwort noch keinen Kommentar abgeben kann):

ls -1 | awk 'ORS=","' | head -c -1

Entfernen Sie einfach so viele nachfolgende Bytes, wie Ihr Begrenzer benötigt.

Ich mag diesen Ansatz, weil ich Trennzeichen mit mehreren Zeichen und andere Vorteile von awk verwenden kann:

ls -1 | awk 'ORS=", "' | head -c -2

EDIT

Wie Peter bemerkt hat, wird die Anzahl negativer Bytes in der nativen MacOS-Version von head nicht unterstützt. Dies kann jedoch leicht behoben werden.

Installieren Sie zunächst coreutils. "Die GNU Core Utilities sind die grundlegenden Hilfsprogramme für die Datei-, Shell- und Textbearbeitung des Betriebssystems GNU."

brew install coreutils

Befehle, die auch von MacOS bereitgestellt werden, werden mit dem Präfix "g" installiert. Zum Beispiel gls.

Sobald Sie dies erledigt haben, können Sie ghead mit negativer Byteanzahl oder besser verwenden, um einen Alias ​​zu erstellen:

alias head="ghead"

ls hat die Option -m, um die Ausgabe mit ", ", einem Komma und einem Leerzeichen, abzugrenzen.

ls -m | tr -d ' ' | tr ',' ';'

wenn Sie dieses Ergebnis an tr weiterleiten, um entweder das Leerzeichen oder das Komma zu entfernen, können Sie das Ergebnis erneut an tr weiterleiten, um das Trennzeichen zu ersetzen.

in meinem Beispiel ersetze ich das Trennzeichen , durch das Trennzeichen ;

ersetzen Sie ; mit einem beliebigen Ein-Zeichen-Trennzeichen, da tr nur das erste Zeichen in den Zeichenfolgen berücksichtigt, die Sie als Argumente übergeben.

0
Andy

Sie können chomp verwenden, um mehrere Zeilen in einer Zeile zusammenzuführen:

Perl -e 'while (<>) {if (/\$ /) {chomp; } print;} 'bad0> test

setzen Sie eine Zeilenumbruchbedingung in die if-Anweisung. Dies kann ein Sonderzeichen oder ein beliebiges Trennzeichen sein.

0
Suman

Quick Perl-Version mit nachfolgendem Schrägstrich:

ls -1 | Perl -E 'say join ", ", map {chomp; $_} <>'

Erklären:

  • Perl -E: Perl mit Features ausführen (zB ...)
  • sagen Sie: Drucken Sie mit einem Träger zurück
  • join ",", ARRAY_HERE: Füge ein Array mit ","
  • map {chomp; $ _} ROWS: Entferne aus jeder Zeile den Carrier Return und gib das Ergebnis zurück
  • <>: stdin, jede Zeile ist eine REIHE, in Verbindung mit einer Karte wird ein Array von jeder REIHE erstellt
0
Celogeek San