2010-03-13 57 views

Trả lời

249

head mất những dòng đầu tiên từ một tập tin, và các thông số -n có thể được dùng để xác định có bao nhiêu dòng nên được trích xuất:

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

Chi phí cao hơn đáng kể so với phương pháp 'đọc'. '$()' tắt một nhánh con và sử dụng lệnh bên ngoài (* bất kỳ * lệnh bên ngoài) có nghĩa là bạn đang gọi 'execve()', gọi trình liên kết và trình tải (nếu nó sử dụng thư viện dùng chung, thường là trường hợp), v.v. –

+1

Nó thậm chí có thể ngắn hơn: 'line =" $ (đầu -1 FILENAME) "' – nikolay

+0

Và cũng: 'line = \' head -1 FILENAME \ '' –

9
line=$(head -1 file) 

sẽ hoạt động tốt. (Như câu trả lời trước). Nhưng

line=$(read -r FIRSTLINE < filename) 

sẽ nhanh hơn một chút là read là lệnh bash được cài sẵn.

+17

Phương pháp thứ hai không hoạt động như được viết , bởi vì 'read' không in bất cứ thứ gì (vì vậy' line' gió lên trống), và cũng thực thi trong một subshell (vì vậy 'FIRSTLINE' được đặt thành dòng đầu tiên, nhưng chỉ trong subshell, vì vậy nó không có sẵn sau đó) .Giải pháp: chỉ sử dụng 'read -r line

35

để đọc dòng đầu tiên bằng bash, sử dụng câu lệnh read. ví dụ

read -r firstline<file 

firstline sẽ biến của bạn (Không cần phải gán cho khác)

+0

thử với' cat ... | đọc -r VAR' và nó không thành công: ( – sorin

+0

Làm thế nào để bạn đọc dòng thứ hai? – qed

+1

@sorin, 'cat ... | đọc VAR' sẽ thất bại trong hầu hết các shell (tất cả ngoại trừ' zsh' theo như tôi biết) bởi vì Mỗi thành phần trong một đường ống sẽ chạy trong các subshells riêng biệt, có nghĩa là '$ VAR' sẽ được đặt trong subshell (không còn tồn tại ngay khi đường dẫn đã hoàn thành) thay vì trong shell gọi. với 'read VAR << EOF \ n $ (cat ...) \ nEOF' (trong đó mỗi' \ n' là một dòng mới) – zrajm

8

này cũng đủ và lưu trữ các dòng đầu tiên của filename trong biến $line:

read -r line < filename 

Tôi cũng thích awk cho điều này:

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

Để lưu trữ chính dòng đó, hãy sử dụng cú pháp var=$(command). Trong trường hợp này, line=$(awk 'NR==1 {print; exit}' file).

Hoặc thậm chí sed:

sed -n '1p' file 

Với tương đương line=$(sed -n '1p' file).


Xem một mẫu khi chúng ta ăn read với seq 10, có nghĩa là, một chuỗi các con số từ 1 đến 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'' (hoặc' sed -n '1p; q'') sẽ bắt chước ký tự' awk' logi của bạn c và ngăn chặn đọc thêm vào tệp. Vì chúng ta chỉ muốn dòng đầu tiên, chúng ta có thể thay thế bằng 'sed q' hoặc 'awk' 1; {exit} '' hoặc thậm chí 'grep -m1 ^' (ít mã, cùng một logic cần thiết). (Đây không phải là câu trả lời cho cuộc điều tra downvote.) –

+0

@AdamKatz đó là một cách rất hay, cảm ơn! Tôi tìm thấy một với 'grep' rất thông minh. Tất nhiên chúng ta cũng có thể nói 'head -n 1 file'. – fedorqui

+0

Có, 'head -n1' sẽ nhanh hơn (nhị phân nhỏ hơn để tải) và' read' sẽ nhanh nhất (không có nhị phân để tải, đó là một nội trang). Tôi đặc biệt thích 'grep -m1 --color .' khi tôi chỉ in dòng đầu tiên bởi vì nó sẽ tô màu cho đường thẳng, làm cho nó tuyệt vời cho các tiêu đề bảng. –

4

Câu hỏi không hỏi đó là nhanh nhất, nhưng để thêm cho câu trả lời sed, -n '1p' hoạt động kém vì không gian mẫu vẫn được quét trên các tệp lớn. Ra khỏi tò mò tôi thấy rằng 'đầu' thắng trên sed trong gang tấc:

# 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

Chỉ echo danh sách đầu tiên của file gốc của bạn vào tập tin mục tiêu của bạn.

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

Trong đó 'head -n 1 source.txt> target.txt' sẽ thực hiện chính xác như nhau. – YoYo

Các vấn đề liên quan