@mattdm Using lsfunktioniert nicht, wenn einer der Dateinamen ein Leerzeichen enthält.
Hilfemethode
2
Wie definierst du ein Wort ? Wenn die erste Datei ist Sunset on a beach.jpg, sollte es sein Sunsetoder der gesamte Dateiname? Was ist Sea, sex and sun.ogg? Sea, Sea,Oder der gesamte Dateiname?
Stéphane Chazelas
@mattdm ls | head -1gibt mir zufällige Dinge wie a.patch p.pydas, was nicht das erste Wort ist und nicht einmal Dateien in alphabetischer Reihenfolge.
Phuclv
Antworten:
52
Sie können es durch awk leiten und es das erste Wort wiedergeben lassen
echo *| head -n1 | awk '{print $1;}'
oder du schneidest den String auf und wählst das erste Wort:
echo *| head -n1 | cut -d " "-f1
oder Sie leiten es durch und lassen es alles bis auf das erste Wort entfernen
echo *| head -n1 | sed -e 's/\s.*$//'
Fügte hinzu | head -n1, um Nitpicker zufriedenzustellen. Wenn Ihre Zeichenfolge Zeilenumbrüche enthält, | head -n1wird zuerst die erste Zeile ausgewählt, bevor die wichtigen Befehle das erste Wort aus der an sie übergebenen Zeichenfolge auswählen.
Das würde das erste Wort jeder Zeile zurückgeben, nicht das erste Wort.
Stéphane Chazelas
2
Ich frage mich, wie viele Zeilen echo *generiert
Bananguin
Dies hängt davon ab, wie viele Dateien Zeilenumbrüche enthalten oder je nach Umgebung oder wie die Bash kompiliert wurde oder ob eine Datei mit dem Namen -eoder -ee... in der Liste aufgeführt ist und wie \noft sie in einem Dateinamen enthalten ist. Wenn eine Datei aufgerufen wird -n, gibt sie möglicherweise nicht einmal eine Zeile zurück ...
Stéphane Chazelas
Nun, wir sprechen immer noch von bash und 1. normalerweise übergibt bash einen String mit Newlines nicht als einen String mit Newlines. 2. Es ist sehr schwierig und ungewöhnlich (unmöglich?), Einen Newline in einem Dateinamen zu haben. 3. a \ n in Ein Dateiname wird als \ n angezeigt. 4. 3 gilt für Dateinamen, die mit - 5 beginnen. Selbst wenn Sie mit -n oder -e aufgerufen werden, wird stdout geöffnet und geschlossen, wenn dies erledigt ist. Natürlich wird eine Zeile zurückgegeben und um Mindestens eine Zeichenfolge, für diese Angelegenheit 6. Ich habe meinen Rat bearbeitet, um zumindest das mehrzeilige Problem zu lösen
Bananguin
1
Alle 5 Punkte sind falsch. Versuchen Sie es in einem leeren Verzeichnis: touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'( xpg_echoist aktiviert, wo bashimmer Unix-konform sein muss). Und in einem anderen leeren Verzeichnis: touch ./-n; bash -c 'echo * | wc -l'. Eine Zeile ist eine Folge von Zeichen, die durch ein Zeilenumbruchzeichen abgeschlossen werden. Wenn echokein Zeilenumbruchzeichen ausgegeben wird, wird keine Zeile ausgegeben. Verhalten von Text - Utilities wie cut, awkoder sedist nicht spezifiziert , wenn die Eingabe zusätzliche Zeichen hat nach dem letzten Newline - Zeichen und das Verhalten gegenüber Implementierungen variieren.
Stéphane Chazelas
18
Angenommen, eine Posixy-Shell ( /bin/shoder /bin/bashkann dies tun)
all=$(echo *)
first=${all%%*}
Das Konstrukt ${all%% *}ist ein Beispiel für das Entfernen von Teilzeichenfolgen . Das %%Mittel löscht die längste Übereinstimmung von *(ein Leerzeichen, gefolgt von irgendetwas) vom rechten Ende der Variablen all. Weitere Informationen zur Manipulation von Zeichenfolgen finden Sie hier .
Diese Lösung setzt voraus, dass das Trennzeichen ein Leerzeichen ist. Wenn Sie dies mit Dateinamen tun, wird dies durch Leerzeichen aufgehoben.
Schön. Aber ich mochte die einfache und non-hacky andere Version mit headundcut
Anwar
4
IMO, Head, Cut & Sed sind weniger einfach. Warum ein anderes Werkzeug erzeugt wird, wenn die eingebaute Parameterersetzung die Arbeit effizient erledigt? Diese Antwort ist die effizienteste und übertragbarste Methode, um das erste Wort einer Liste von durch Leerzeichen getrennten Wörtern (nach denen alle OPs gefragt haben) herauszusuchen.
Juan
7
Angenommen, Sie möchten wirklich den ersten Dateinamen und nicht das erste Wort , dann haben wir einen Weg, der bei Leerzeichen nicht bricht:
Das erste Wort wäre auch einfach:files=($(echo *))
Hauke Laging
2
Es würde auf "-n", "-e", "-ne", "-Enenene" ... und abhängig von der bashKompilierung oder der Umgebung, möglicherweise jedoch auf Backslash-Zeichen, aufbrechen.
Stéphane Chazelas
2
@HaukeLaging, Sie müssen das Globbing deaktivieren. Wie:, text=$(echo *); set -f; files=($text)sonst könnten mehr Wildcards erweitert werden.
Stéphane Chazelas
3
undfiles=$(echo *); echo ${files%% *}
vdegenne
1
@memnoch_proxy Bei Dateinamen, die Leerzeichen enthalten, tritt ein Fehler auf. Verwenden Sie diese Option mit Vorsicht.
Beachten Sie, dass dadurch alle anderen Argumente für Ihr Skript zerstört werden, sofern sie nicht in einem Hilfsbereich ausgeführt werden. Es wird auch erweitert, *wenn sich keine Dateien im Verzeichnis befinden.
ls
funktioniert nicht, wenn einer der Dateinamen ein Leerzeichen enthält.Sunset on a beach.jpg
, sollte es seinSunset
oder der gesamte Dateiname? Was istSea, sex and sun.ogg
?Sea
,Sea,
Oder der gesamte Dateiname?ls | head -1
gibt mir zufällige Dinge wiea.patch p.py
das, was nicht das erste Wort ist und nicht einmal Dateien in alphabetischer Reihenfolge.Antworten:
Sie können es durch awk leiten und es das erste Wort wiedergeben lassen
oder du schneidest den String auf und wählst das erste Wort:
oder Sie leiten es durch und lassen es alles bis auf das erste Wort entfernen
Fügte hinzu
| head -n1
, um Nitpicker zufriedenzustellen. Wenn Ihre Zeichenfolge Zeilenumbrüche enthält,| head -n1
wird zuerst die erste Zeile ausgewählt, bevor die wichtigen Befehle das erste Wort aus der an sie übergebenen Zeichenfolge auswählen.quelle
echo *
generiert-e
oder-ee
... in der Liste aufgeführt ist und wie\n
oft sie in einem Dateinamen enthalten ist. Wenn eine Datei aufgerufen wird-n
, gibt sie möglicherweise nicht einmal eine Zeile zurück ...touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'
(xpg_echo
ist aktiviert, wobash
immer Unix-konform sein muss). Und in einem anderen leeren Verzeichnis:touch ./-n; bash -c 'echo * | wc -l'
. Eine Zeile ist eine Folge von Zeichen, die durch ein Zeilenumbruchzeichen abgeschlossen werden. Wennecho
kein Zeilenumbruchzeichen ausgegeben wird, wird keine Zeile ausgegeben. Verhalten von Text - Utilities wiecut
,awk
odersed
ist nicht spezifiziert , wenn die Eingabe zusätzliche Zeichen hat nach dem letzten Newline - Zeichen und das Verhalten gegenüber Implementierungen variieren.Angenommen, eine Posixy-Shell (
/bin/sh
oder/bin/bash
kann dies tun)Das Konstrukt
${all%% *}
ist ein Beispiel für das Entfernen von Teilzeichenfolgen . Das%%
Mittel löscht die längste Übereinstimmung von*
(ein Leerzeichen, gefolgt von irgendetwas) vom rechten Ende der Variablenall
. Weitere Informationen zur Manipulation von Zeichenfolgen finden Sie hier .Diese Lösung setzt voraus, dass das Trennzeichen ein Leerzeichen ist. Wenn Sie dies mit Dateinamen tun, wird dies durch Leerzeichen aufgehoben.
quelle
head
undcut
Angenommen, Sie möchten wirklich den ersten Dateinamen und nicht das erste Wort , dann haben wir einen Weg, der bei Leerzeichen nicht bricht:
quelle
files=($(echo *))
bash
Kompilierung oder der Umgebung, möglicherweise jedoch auf Backslash-Zeichen, aufbrechen.text=$(echo *); set -f; files=($text)
sonst könnten mehr Wildcards erweitert werden.files=$(echo *); echo ${files%% *}
Sie können die Positionsparameter verwenden
quelle
*
wenn sich keine Dateien im Verzeichnis befinden.shopt -s nullglob
würde damit umgehenAktivieren Sie eine der folgenden Alternativen:
Dann können Sie es über ausdrucken
echo $FILE
.Siehe auch:
grep
Das einzige erste Wort aus der Ausgabe?quelle
Das funktioniert:
Creds zu https://unix.stackexchange.com/a/57879/3920
quelle
Den ganzen ersten Dateinamen erhalten:
quelle