2010-03-13 4 views

ответ

249

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

line=$(head -n 1 filename) 
+1

Значительно больше накладных расходов, чем подход 'read'. '$()' отбрасывает подоболочку и использование внешней команды (* любая * внешняя команда) означает, что вы вызываете 'execve()', вызывая компоновщик и загрузчик (если он использует разделяемые библиотеки, что обычно имеет место) и т. д. –

+1

Это может быть еще короче: 'line =" $ (head -1 FILENAME) "' – nikolay

+0

А также: 'line = \' head -1 FILENAME \ '' –

9
line=$(head -1 file) 

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

line=$(read -r FIRSTLINE < filename) 

будет немного быстрее, так как read является встроенной командой Баш.

+17

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

35

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

read -r firstline<file 

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

+0

, пробовали с' cat ... | прочитайте -r VAR', и он не сработает :( – sorin

+0

Как вы читаете вторую строку? – qed

+1

@sorin, 'cat ... | read VAR' провалится в большинстве оболочек (все, кроме' zsh', насколько я знаю), потому что каждый из компонентов в трубе будет запускаться в отдельных подоболочках. Значение «$ VAR» будет установлено в подоболочке (которое перестанет существовать, как только конвейер завершит выполнение), а не в вызывающей оболочке. с 'read VAR << EOF \ n $ (cat ...) \ nEOF' (где каждая' \ n' является новой строкой). – zrajm

8

Этого достаточно и сохраняет первую строку 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' logi c и не допускать дальнейшего чтения в файл. Поскольку мы хотим только первую строку, мы можем поочередно обманывать с помощью 'sed q' или' awk '1; {exit}' 'или даже' grep -m1^'(меньше кода, такой же основной логики). (Это не ответ на запрос downvote.) –

+0

@AdamKatz это очень хороший набор способов, спасибо! Я нахожу, что с «grep» очень умный. Разумеется, мы также можем сказать «head -n 1 file». – fedorqui

+0

Да, 'head -n1' будет быстрее (меньший двоичный файл для загрузки), а' read' будет самым быстрым (нет бинарных файлов для загрузки, это встроенный). Мне особенно нравится «grep -m1 --color.», Когда я просто печатаю первую строку, потому что она тоже окрасит линию, что делает ее отличной для заголовков таблиц. –

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 
3

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

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

Для чего 'head -n 1 source.txt> target.txt' будет выполняться точно так же. – YoYo

Смежные вопросы