Як отримати перший рядок файлу в bash-скрипті?


249

Я повинен помістити в змінну bash перший рядок файлу. Я думаю, це з командою grep, але будь-який спосіб обмежити кількість рядків?

Відповіді:


397

headприймає перші файли з файлу, і -nпараметр може бути використаний для визначення кількості рядків, які слід витягти:

line=$(head -n 1 filename)

3
Значно більше накладних витрат, ніж readпідхід. $()розщеплює підшлунок, а використання зовнішньої команди ( будь-якої зовнішньої команди) означає, що ви дзвоните, викликаєте execve()посилання та завантажувач (якщо він використовує спільні бібліотеки, що зазвичай буває) тощо.
Чарльз Даффі

2
Це могло бути і коротше:line="$(head -1 FILENAME)"
nikolay

3
А також:line=`head -1 FILENAME`
Шай Алон

Чи є задні підказки навколо head...відкритої нижньої частини корпусу $()?
Хайме Хаблуцель

@JaimeHablutzel Так, вони те саме, хоча я особисто вважаю, що $()синтаксис легше бачити і цінність ясності порівняно з абсолютною строгістю. gnu.org/software/bash/manual/html_node/…
Йосип Сікорський

61

для читання першого рядка за допомогою bash, використовуйте readоператор. напр

read -r firstline<file

firstline буде вашою змінною (Не потрібно призначати іншу)


1
@sorin, cat ... | read VARвийде з ладу у більшості оболонок (усі, крім zshмоїх відомостей), оскільки кожен з компонентів у трубі буде працювати в окремих підгруппах. Це означає, що $VARбуде встановлено в нижній частині корпусу (який перестане існувати, як тільки конвеєр закінчить виконання), а не в оболонці, що викликає. Ви можете обійти це за допомогою read VAR <<EOF\n$(cat ...)\nEOF(де кожен \n- це новий рядок).
zrajm

@sorin, catчистий накладні витрати; набагато ефективніший, read -r var <fileніж cat file | readбудь-який спосіб, навіть якщо останні не вийшли з ладу з причин, описаних у BashFAQ # 24 .
Чарльз Даффі

... якщо у вас працює щось більше, ніж catтоді,read -r var < <(otherprog ...)
Чарльз Даффі

14

Цього достатньо і зберігається перший рядок filenameзмінної $line:

read -r line < filename

Мені також подобається awkце:

awk 'NR==1 {print; exit}' file

Для збереження самого рядка використовуйте var=$(command)синтаксис. У цьому випадку line=$(awk 'NR==1 {print; exit}' file).

Або навіть sed:

sed -n '1p' file

З еквівалентом line=$(sed -n '1p' file).


Дивіться зразок, коли ми годуємо read з seq 10, тобто послідовність чисел від 1 до 10:

$ read -r line < <(seq 10) 
$ echo "$line"
1

$ line=$(awk 'NR==1 {print; exit}' <(seq 10))
$ echo "$line"
1

1
sed '1!d;q'(або sed -n '1p;q') буде імітувати вашу awkлогіку та заважати читати далі у файлі. Тому що ми тільки хочемо перший рядок, ми можемо в якості альтернативи обдурити з sed qабо awk '1;{exit}'навіть grep -m1 ^(менше коду, так само важливо логіка). (Це не відповідь на запит, що проводиться нижче.)
Адам Кац

@AdamKatz, це дуже приємний набір способів, дякую! Я вважаю, що grepдуже розумний. Можна, звичайно, також сказати head -n 1 file.
fedorqui 'ТАК перестаньте шкодити'

Так, head -n1буде швидше (менший двійковий для завантаження) і readбуде найшвидшим (не бінарне для завантаження, це вбудований). Особливо мені подобається, grep -m1 --color .коли я просто друкую перший рядок, тому що він також забарвлює лінію, що робить його чудовим для заголовків таблиці.
Адам Кац

12
line=$(head -1 file)

Буде добре працювати. (Як попередня відповідь). Але

line=$(read -r FIRSTLINE < filename)

буде незначно швидше, як readі вбудована команда bash.


21
Другий метод не працює так, як написано, тому що він readнічого не друкує (так що він lineзавершується порожнім), а також виконується в підзарядці (так FIRSTLINEвстановлюється в перший рядок, але тільки в нижній частині, тому він згодом недоступний). Рішення: просто використовуйтеread -r line <filename
Гордон Девіссон

5

Просто echoперший список вихідного файлу у ваш цільовий файл.

echo $(head -n 1 source.txt) > target.txt

3
Для якого head -n 1 source.txt > target.txtдосягти точно так само.
YoYo

4

Питання не задавало те, що найшвидше, але щоб додати відповідь sed, -n '1p' погано спрацьовує, оскільки простір шаблонів все ще сканується на великих файлах. З цікавості я виявив, що "голова" перемагає сідаль:

# best:
head -n1 $bigfile >/dev/null

# a bit slower than head (I saw about 10% difference):
sed '1q' $bigfile >/dev/null

# VERY slow:
sed -n '1p' $bigfile >/dev/null
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.