Как получить первую строку файла в bash-скрипте?

249

Я должен поместить в переменную bash первую строку файла. Я думаю, что это с командой grep, но есть ли способ ограничить количество строк?

Neuquino
источник

Ответы:

397

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

line=$(head -n 1 filename)
STH
источник
3
Значительно больше накладных расходов, чем readподход. $()разветвляется на подоболочку, и использование внешней команды ( любой внешней команды) означает, что вы звоните execve(), вызываете компоновщик и загрузчик (если он использует разделяемые библиотеки, как это обычно бывает) и т. д.
Чарльз Даффи,
2
Это может быть еще короче:line="$(head -1 FILENAME)"
Николай
3
А также:line=`head -1 FILENAME`
Шай Алон
Делает ли backticks вокруг head...открытия подоболочку $()?
Хайме
@JaimeHablutzel Да, это одно и то же, хотя лично я нахожу, что $()синтаксис легче увидеть и ценит ясность, а не абсолютную краткость. gnu.org/software/bash/manual/html_node/…
Джозеф Сикорский
61

чтобы прочитать первую строку, используя bash, используйте readоператор. например

read -r firstline<file

firstline будет вашей переменной (нет необходимости назначать другим)

ghostdog74
источник
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 .
Чарльз Даффи
... если у вас что-то более catread -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.
Федорки "ТАК прекратить причинять вред"
Да, head -n1будет быстрее (меньший двоичный файл для загрузки) и readбудет самым быстрым (без двоичного файла для загрузки, это встроенный). Мне особенно нравится, grep -m1 --color .когда я просто печатаю первую строку, потому что она также будет окрашивать линию, что отлично подходит для заголовков таблиц.
Адам Кац
12
line=$(head -1 file)

Будет работать нормально. (Как и предыдущий ответ). Но

line=$(read -r FIRSTLINE < filename)

будет немного быстрее, чем readвстроенная команда bash.

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

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

echo $(head -n 1 source.txt) > target.txt
openwonk
источник
3
За что и head -n 1 source.txt > target.txtсделаю точно так же.
Йо-
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
Нил МакГилл
источник