Bir bash betiğinde bir dosyanın ilk satırını nasıl edinebilirim?


249

Bir bash değişkeni bir dosyanın ilk satırını koymak zorunda. Ben grep komutu ile sanırım, ama satır sayısını sınırlamak için herhangi bir yoludur?

Yanıtlar:


397

headdosyadan ilk satırları alır ve -nparametre kaç satırın ayıklanması gerektiğini belirtmek için kullanılabilir:

line=$(head -n 1 filename)

3
readYaklaşımdan önemli ölçüde daha fazla yük . $()bir alt kabuğu çatalla ve harici bir komut ( herhangi bir harici komut) kullanmak, aradığınız execve(), bağlayıcıyı ve yükleyiciyi çağırdığınız anlamına gelir (genellikle böyle olan paylaşılan kütüphaneler kullanıyorsa, vb.)
Charles Duffy

2
Daha da kısa olabilir:line="$(head -1 FILENAME)"
nikolay

3
Ve ayrıca:line=`head -1 FILENAME`
Shai Alon

Etraftaki backticks head...olduğu gibi bir alt kabuk açar $()mı?
Jaime Hablutzel

@JaimeHablutzel Evet, onlar aynı şey, ancak kişisel olarak $()sözdiziminin görülmesinin daha kolay olduğunu ve mutlak terslik karşısında netliğe değer verdiğini düşünüyorum. gnu.org/software/bash/manual/html_node/…
Joseph Sikorski

61

bash kullanarak ilk satırı okumak için readdeyimi kullanın . Örneğin

read -r firstline<file

firstline değişkeniniz olacak (başkasına atamanıza gerek yok)


1
@sorin, cat ... | read VARçoğu mermide başarısız olur ( zshbildiğim kadarıyla hariç ) çünkü bir borudaki bileşenlerin her biri ayrı alt kabuklarda çalışacaktır. Bu $VAR, çağrılan kabuktan ziyade alt kabukta (boru hattının yürütülmesi biter bitmez varolması) ayarlanacak anlamına gelir . Bununla read VAR <<EOF\n$(cat ...)\nEOF(her birinin \nyeni satır olduğu) bu sorunu çözebilirsiniz .
17'de zrajm

@sorin, catsaf yük; çok daha verimli için read -r var <filedaha cat file | readnasıl olsa bile eğer ikincisi açıklanan nedenlerle başarısız olmamış BashFAQ # 24 .
Charles Duffy

... eğer bundan daha karmaşık bir şey yönetiyorsanız cat, o zamanread -r var < <(otherprog ...)
Charles Duffy

14

Bu filename, değişkenin ilk satırını yeterlidir ve saklar $line:

read -r line < filename

Ben de awkbunun için:

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

Çizginin kendisini saklamak için var=$(command)sözdizimini kullanın. Bu durumda line=$(awk 'NR==1 {print; exit}' file),.

Hatta sed:

sed -n '1p' file

Eşdeğeri ile line=$(sed -n '1p' file).


Besleyecek Bir örnek bakınız readile seq 101 ila 10 bir sayı dizisi olduğunu:

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

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

1
sed '1!d;q'(veya sed -n '1p;q') awkmantığınızı taklit eder ve dosyanın daha fazla okunmasını önler. Biz sadece ilk satırı istediğimiz için, alternatif ile hile sed qveya awk '1;{exit}'hatta grep -m1 ^(daha az kod, aynı temel mantık). (Bu, downvote soruşturmasının bir cevabı değildir.)
Adam Katz

@AdamKatz bu çok güzel bir dizi yol, teşekkürler! grepÇok akıllı olanı buluyorum . Tabii ki de söyleyebiliriz head -n 1 file.
fedorqui 'SO

Evet, head -n1daha hızlı (yüklenecek daha küçük ikili) ve readen hızlı olacak (yüklenecek ikili değil, bu bir yerleşiktir). Özellikle grep -m1 --color .sadece ilk satırı yazdırdığımda hoşuma gidiyor çünkü çizgiyi de renklendirecek ve tablo başlıkları için harika olacak.
Adam Katz

12
line=$(head -1 file)

İyi çalışır. (Önceki cevap olarak). Fakat

line=$(read -r FIRSTLINE < filename)

readyerleşik bir bash komutu gibi marjinal olarak daha hızlı olacaktır .


21
İkinci yöntem yazılı olarak readçalışmaz , çünkü hiçbir şey yazdırmaz (bu nedenle lineboştur) ve ayrıca bir alt kabukta yürütülür (bu nedenle FIRSTLINEilk satıra ayarlanır, ancak yalnızca alt kabukta bulunur, bu nedenle daha sonra kullanılamaz). Çözüm: sadece kullanınread -r line <filename
Gordon Davisson

5

Sadece echohedef dosyaya kaynak dosyasının ilk listesi.

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

3
Hangi için head -n 1 source.txt > target.txttam olarak aynı başarır.
YoYo

4

Soru hangisinin en hızlı olduğunu sormadı, ancak sed cevabına eklemek için -n '1p', desen alanı hala büyük dosyalarda tarandığından kötü performans gösteriyor. Meraktan 'kafa' nın dar bir şekilde kazanacağını fark ettim:

# 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.