bashスクリプトでファイルの最初の行を取得する方法は?


249

ファイルの最初の行をbash変数に入れる必要があります。それはgrepコマンドであると思いますが、行数を制限する方法はありますか?

回答:


396

headファイルから最初の行を取得し、-nパラメータを使用して、抽出する行数を指定できます。

line=$(head -n 1 filename)

3
readアプローチよりも大幅に多くのオーバーヘッド。$()サブシェルをforkし、外部コマンド(任意の外部コマンド)を使用するとexecve()、が呼び出され、リンカーとローダーが呼び出されます(共有ライブラリを使用している場合(通常))
Charles Duffy

2
それも、短くすることができます:line="$(head -1 FILENAME)"
ニコライ・

3
また、line=`head -1 FILENAME`
Shai Alon 2018

head...オープンの周りのバッククォートはサブシェルを開くのです$()か?
Jaime Hablutzel、

@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 2017年

@sorin catは純粋なオーバーヘッドです。はるかに効率的にread -r var <fileよりcat file | readとにかく、でもあれば後者はで説明した理由で失敗しませんでしたBashFAQ#24
Charles Duffy 2017

...あなたはよりも複雑な何かを実行している場合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)


readwith 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 qor awk '1;{exit}'またはor grep -m1 ^(もっと少ないコード、同じ基本ロジック)でチートすることもできます。(これは反対投票の質問に対する回答ではありません。)
アダムKatz

@AdamKatzそれは非常に素晴らしい方法のセットです、ありがとう!grepとてもスマートなものを見つけました。もちろん言うこともできますhead -n 1 file
fedorqui 'SO stop harming' 2016

はい、head -n1より速く(ロードするバイナリは小さい)、read最も速くなります(ロードするバイナリはなく、組み込みです)。特にgrep -m1 --color .、最初の行を印刷するときは、線も色付けされるので、表の見出しに最適です。
Adam Katz、

12
line=$(head -1 file)

正常に動作します。(以前の回答と同様)。だが

line=$(read -r FIRSTLINE < filename)

read組み込みのbashコマンドと同様に、わずかに高速になります。


21
2番目の方法は、read何も出力しないため(line空白になるため)、記述どおりに機能せず、サブシェルでも実行されます(そのためFIRSTLINE、最初の行に設定されますが、サブシェルでのみ実行されるため、後で使用できません)。解決策:そのまま使用してくださいread -r line <filename
Gordon Davisson

5

echoソースファイルの最初のリストをターゲットファイルに追加するだけです。

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

3
そのためhead -n 1 source.txt > target.txt、正確に同じことを実現します。
YoYo

4

質問ではどちらが最も速いかは尋ねられませんでしたが、sedの回答に追加するために、-n '1p'は、パターンスペースが依然として大きなファイルでスキャンされるため、パフォーマンスが低下しています。好奇心から、私は「頭」が狭くsedに勝っていることがわかりました:

# 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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.