@mattdm Korzystanie lsnie działa, jeśli jeden z nazw plików zawiera spację.
helpermethod
2
Jak definiujesz słowo ? Jeśli pierwszy plik to Sunset on a beach.jpg, czy powinien to być Sunsetcały plik? Co Sea, sex and sun.ogg? Sea, Sea,Lub cała nazwa pliku?
Stéphane Chazelas
@mattdm ls | head -1daje mi losowe rzeczy, takie jak a.patch p.pyktóre nie jest pierwszym słowem, a nawet pliki w kolejności alfabetycznej.
phuclv
Odpowiedzi:
52
Możesz przerzucić go przez awk i sprawić, by powtórzył pierwsze słowo
echo *| head -n1 | awk '{print $1;}'
lub przeciąć ciąg i wybrać pierwsze słowo:
echo *| head -n1 | cut -d " "-f1
lub potokujesz go przez sed i każesz usunąć wszystko oprócz pierwszego słowa
echo *| head -n1 | sed -e 's/\s.*$//'
Dodano, | head -n1aby zaspokoić nitpickers. W przypadku, gdy Twój ciąg zawiera nowe linie, | head -n1najpierw wybierze pierwszy wiersz, zanim ważne polecenia wybiorą pierwsze słowo z przekazanego mu ciągu.
Zwraca pierwsze słowo każdego wiersza, a nie pierwsze słowo.
Stéphane Chazelas
2
Zastanawiam się, ile linii echo *generuje
Bananguin
Zależy to od tego, ile plików ma w nazwie znaki nowego wiersza lub w zależności od środowiska, jak skompilowano bash, czy na liście pojawi się jakiś plik o nazwie -elub -ee..., ile czasu \npojawia się w nazwie pliku. Jeśli istnieje plik o nazwie -n, może nawet nie zwrócić żadnej linii ...
Stéphane Chazelas
Cóż, wciąż mówimy o bashu i 1. zwykle bash nie przejdzie ciągu z nowymi liniami jak jeden ciąg z nowymi liniami 2. bardzo trudno i nietypowo (niemożliwe?) Mieć nowy wiersz w nazwie pliku 3. a \ n w nazwa pliku pojawi się jako \ n 4. 3 wstrzymuje nazwy plików zaczynające się na - 5. nawet jeśli wywoływane przez -n lub -e echo otworzy standardowe wyjście i zamknie je, kiedy to zrobione, więc oczywiście zwróci linię i na przynajmniej jeden ciąg, jeśli chodzi o to 6. Zredagowałem moją radę, aby przynajmniej zająć się problemem multilinii
Bananguin
1
Wszystkie 5 punktów są fałszywe. Spróbuj w pustym katalogu: touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'( xpg_echojest włączony wszędzie tam, gdzie bashwymagana jest zgodność z Uniksem). A w innym pustym katalogu: touch ./-n; bash -c 'echo * | wc -l'. Linia to ciąg znaków zakończony znakiem nowej linii. Jeśli echonie wypisuje znaku nowej linii, nie wypisuje żadnego wiersza. Zachowanie narzędzi tekstowych podoba cut, awkczy sedjest nieokreślony, jeżeli wejście ma dodatkowych znaków po ostatni znak nowej linii i zachowanie różni się w poszczególnych wdrożeń.
Stéphane Chazelas,
18
Zakładając posixy shell ( /bin/shlub /bin/bashmożna to zrobić)
all=$(echo *)
first=${all%%*}
Konstrukt ${all%% *}jest przykładem usuwania podciągów . Te %%środki usuwać najdłuższy mecz *(spację cokolwiek) od końca prawej zmiennej all. Możesz przeczytać więcej o manipulowaniu łańcuchem tutaj .
To rozwiązanie zakłada, że separator jest spacją. Jeśli robisz to z nazwami plików, każda ze spacjami to zepsuje.
Niezłe. Ale podobała mi się prosta i bardziej nie zhakowana inna wersja z headicut
Anwar
4
IMO, head, cut & sed są mniej proste. Po co spawnować inne narzędzie, gdy wbudowane podstawienie parametrów wykonuje zadanie skutecznie. Ta odpowiedź jest najskuteczniejszym i najbardziej przenośnym sposobem na wybranie pierwszego słowa z listy słów rozdzielonych spacjami (o które poprosił OP).
Juan
7
Zakładając, że naprawdę potrzebujesz pierwszej nazwy pliku, a nie pierwszego słowa , oto sposób, który nie łamie się na białych znakach:
Uszkodziłoby to na „-n”, „-e”, „-ne”, „-Enenene” ... i zależnie od tego, jak bashzostało skompilowane lub środowisko, być może jednak na znakach odwrotnego ukośnika.
Stéphane Chazelas
2
@HaukeLaging, musisz wyłączyć globowanie. Na przykład: text=$(echo *); set -f; files=($text)w przeciwnym razie można by rozszerzyć więcej symboli wieloznacznych.
Stéphane Chazelas
3
ifiles=$(echo *); echo ${files%% *}
vdegenne
1
@memnoch_proxy Spowoduje to uszkodzenie nazw plików zawierających białe znaki, używaj go ostrożnie.
Pamiętaj, że spowoduje to zniszczenie wszelkich innych argumentów skryptu, chyba że zostanie uruchomiony w zakresie pomocniczym. Rozwinie się również, *jeśli w katalogu nie ma żadnych plików.
ls
nie działa, jeśli jeden z nazw plików zawiera spację.Sunset on a beach.jpg
, czy powinien to byćSunset
cały plik? CoSea, sex and sun.ogg
?Sea
,Sea,
Lub cała nazwa pliku?ls | head -1
daje mi losowe rzeczy, takie jaka.patch p.py
które nie jest pierwszym słowem, a nawet pliki w kolejności alfabetycznej.Odpowiedzi:
Możesz przerzucić go przez awk i sprawić, by powtórzył pierwsze słowo
lub przeciąć ciąg i wybrać pierwsze słowo:
lub potokujesz go przez sed i każesz usunąć wszystko oprócz pierwszego słowa
Dodano,
| head -n1
aby zaspokoić nitpickers. W przypadku, gdy Twój ciąg zawiera nowe linie,| head -n1
najpierw wybierze pierwszy wiersz, zanim ważne polecenia wybiorą pierwsze słowo z przekazanego mu ciągu.źródło
echo *
generuje-e
lub-ee
..., ile czasu\n
pojawia się w nazwie pliku. Jeśli istnieje plik o nazwie-n
, może nawet nie zwrócić żadnej linii ...touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'
(xpg_echo
jest włączony wszędzie tam, gdziebash
wymagana jest zgodność z Uniksem). A w innym pustym katalogu:touch ./-n; bash -c 'echo * | wc -l'
. Linia to ciąg znaków zakończony znakiem nowej linii. Jeśliecho
nie wypisuje znaku nowej linii, nie wypisuje żadnego wiersza. Zachowanie narzędzi tekstowych podobacut
,awk
czysed
jest nieokreślony, jeżeli wejście ma dodatkowych znaków po ostatni znak nowej linii i zachowanie różni się w poszczególnych wdrożeń.Zakładając posixy shell (
/bin/sh
lub/bin/bash
można to zrobić)Konstrukt
${all%% *}
jest przykładem usuwania podciągów . Te%%
środki usuwać najdłuższy mecz*
(spację cokolwiek) od końca prawej zmiennejall
. Możesz przeczytać więcej o manipulowaniu łańcuchem tutaj .To rozwiązanie zakłada, że separator jest spacją. Jeśli robisz to z nazwami plików, każda ze spacjami to zepsuje.
źródło
head
icut
Zakładając, że naprawdę potrzebujesz pierwszej nazwy pliku, a nie pierwszego słowa , oto sposób, który nie łamie się na białych znakach:
źródło
files=($(echo *))
bash
zostało skompilowane lub środowisko, być może jednak na znakach odwrotnego ukośnika.text=$(echo *); set -f; files=($text)
w przeciwnym razie można by rozszerzyć więcej symboli wieloznacznych.files=$(echo *); echo ${files%% *}
Możesz użyć parametrów pozycyjnych
źródło
*
jeśli w katalogu nie ma żadnych plików.shopt -s nullglob
poradziłby sobie z tymSprawdź jedną z następujących opcji:
Następnie możesz go wydrukować za pomocą
echo $FILE
.Zobacz także:
grep
jedyne pierwsze słowo z wyników?źródło
To działa:
Podziękowania dla https://unix.stackexchange.com/a/57879/3920
źródło
Uzyskiwanie całej pierwszej nazwy pliku:
źródło