Як отримати перше слово рядка?


43

Коли я 'echo *' отримую такий результат:

file1 file2 file3 ...

Що я хочу - це вибрати перше слово. Як я можу діяти?


1
@mattdm Використання lsне працюватиме, якщо одна з імен файлів містить порожню.
helpermethod

2
Як ви визначаєте слово ? Якщо перший файл є Sunset on a beach.jpg, він повинен бути Sunsetчи ім'ям цілого файлу? Про що Sea, sex and sun.ogg? Sea, Sea,Або ім'я весь файл?
Стефан Шазелас

@mattdm ls | head -1дає мені випадкові речі, такі як a.patch p.pyце не перше слово і навіть файли в алфавітному порядку.
phuclv

Відповіді:


52

Ви можете передати це через awk і зробити це повторенням першого слова

echo * | head -n1 | awk '{print $1;}'

або ви вирізаєте рядок і вибираєте перше слово:

echo *  | head -n1 | cut -d " " -f1

або ви трубите це thorugh sed і маєте його видалити все, крім першого слова

echo * | head -n1 | sed -e 's/\s.*$//'

Додано | head -n1задоволення азотистів. Якщо ваш рядок містить нові рядки | head -n1, виберіть перший рядок спочатку перед важливими командами, виберіть перше слово з переданого до нього рядка.


1
The повертав би перше слово кожного рядка, а не перше слово.
Стефан Шазелас

2
мені цікаво, скільки echo *генерує рядків
Bananguin

Це залежить від того, скільки файлів мають символи нових рядків у своєму імені або залежно від середовища чи того, як був складений bash, чи в списку відображається якийсь файл, викликаний -eчи -ee..., скільки разів \nвідображається в імені файлу. Якщо файл називається -n, він може взагалі не повернути жодного рядка ...
Stéphane Chazelas

Ну, ми все ще говоримо bash і 1. зазвичай bash не передасть рядок з новими рядками, як одна рядок з новими рядками 2. Дуже важко і незвично (неможливо?) Мати новий рядок у назві файлу 3. a \ n у ім'я файлу відображатиметься як \ n 4. 3 утримується для імен файлів, починаючи з - 5. навіть при виклику з -n або -e відлуння відкриє stdout і закриє його, коли це зроблено, звичайно, він поверне рядок, і на принаймні один рядок, з цього приводу 6. Я відредагував свою пораду, щоб принаймні подбати про багатолінійну проблему
Bananguin

1
Усі 5 балів помилкові. Спробуйте в порожньому режимі: touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'( xpg_echoувімкнено, де bashпотрібно, щоб відповідати Unix). А в інший порожній каталог: touch ./-n; bash -c 'echo * | wc -l'. Рядок - це послідовність символів, що закінчується символом нового рядка. Якщо echoне виводиться символ нового рядка, він не виводить жодного рядка. Поведінка текстових утиліт , як cut, awkабо sedне визначений , якщо вхід має додаткові символи після останнього символу нового рядка і поведінку варіюється в залежності від реалізації.
Стефан Шазелас

18

Припускаючи оболонку позикси ( /bin/shабо це /bin/bashможна зробити)

all=$(echo *)
first=${all%% *}

Конструкція ${all%% *}є прикладом видалення підрядків . Засіб %%видаляє найдовший збіг *(пробіл, за яким слід що-небудь) з правого кінця змінної all. Більше про маніпуляції з рядками ви можете прочитати тут .

Це рішення передбачає, що роздільник є пробілом. Якщо ви робите це з іменами файлів, будь-який з пробілами порушить його.


Хороший. Але мені сподобалася проста і більш не хакітлива інша версія з headіcut
Анвар

4
ІМО, голова, вирізання та сед менш прості. Чому нерестовий інший інструмент, коли вбудована заміна параметрів виконує цю роботу ефективно. Ця відповідь є найефективнішим і найбільш портативним способом виділити перше слово з списку розділених пробілами слів (про що вимагає все ОП).
Хуан

7

Припускаючи, що ви дійсно хочете перше ім'я файлу, а не перше слово , ось спосіб, який не розбивається на пробіл:

shopt -s nullglob
files=(*)
printf '%s\n' "${files[0]}"

1
Перше слово теж було б легко:files=($(echo *))
Hauke ​​Laging

2
Він би розбивався на "-n", "-e", "-ne", "-Enenene" ..., і залежно від того, як bashбуло складено або оточення, можливо, на символах зворотної косої риси.
Стефан Шазелас

2
@HaukeLaging, вам потрібно буде відключити глобалізацію. Як, наприклад text=$(echo *); set -f; files=($text), інакше можна буде розширити більше підказок.
Стефан Шазелас

3
іfiles=$(echo *); echo ${files%% *}
vdegenne

1
@memnoch_proxy Він порушить назви файлів, що містять пробіли, використовуйте їх обережно.
Кріс Даун

5

Можна використовувати параметри позиції

set -- *
echo "$1"

3
Майте на увазі, що це знищить будь-які інші аргументи до вашого сценарію, якщо тільки вони не будуть виконані в допоміжній області. Він також розшириться, *якщо в каталозі немає файлів.
Chris Down

shopt -s nullglobвпорався б із цим
Гленн Джекман

3

Перевірте одну з наступних альтернатив:

$ FILE=($(echo *))
$ FILE=$(echo * | grep -o "^\S*")
$ FILE=$(echo * | grep -o "[^ ]*")
$ FILE=$(find . -type f -print -quit)

Потім ви можете роздрукувати його через echo $FILE.

Дивіться також: grepєдине перше слово з виводу?



1

Отримання першого імені файлу:

shopt -s nullglob
printf '%s\000' * | grep -z -m 1 '^..*$'
printf '%s\000' * | ( IFS="" read -r -d "" var; printf '%s\n' "$var" )
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.