如何在bash脚本中获取文件的第一行?


249

我必须将bash变量放在文件的第一行。我猜这是grep命令,但是有什么办法限制行数?

Answers:


396

head从文件中获取第一行,该-n参数可用于指定应提取多少行:

line=$(head -n 1 filename)

3
比该read方法的开销大得多。$()叉关闭子外壳,并使用外部命令(任何外部命令)指你调用execve(),调用链接器和加载器(如果它是一个使用共享库,这通常是这种情况)等
查尔斯达菲

2
它甚至可能更短:line="$(head -1 FILENAME)"
nikolay

3
而且:line=`head -1 FILENAME`
Shai Alon

周围的反引号是否也像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

@sorin cat是纯开销;更有效地read -r var <filecat file | read无论如何,即使如果后者没有失败中描述的原因BashFAQ#24
Charles Duffy

...如果您要进行的工作比涉及的更多cat,那么read -r var < <(otherprog ...)
Charles Duffy

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 qawk '1;{exit}'或甚至grep -m1 ^(更少的代码,相同的基本逻辑)。(这不是对downvote查询的答复。)
Adam Katz

@AdamKatz,这是一组非常好的方法,谢谢!我发现一个grep非常聪明的人。我们当然也可以说head -n 1 file
fedorqui'SO停止伤害

是的,head -n1将会更快(要加载较小的二进制文件)并且read最快(没有要加载的二进制文件,这是内置的)。grep -m1 --color .当我仅打印第一行时,我尤其喜欢它,因为它也会为该行上色,因此非常适合表标题。
亚当·卡兹

12
line=$(head -1 file)

将正常工作。(作为以前的答案)。但

line=$(read -r FIRSTLINE < filename)

会比read内置的bash命令快一些。


21
第二种方法不能按书面要求工作,因为read它不会打印任何内容(因此会变成line空白),并且还在子shell中执行(因此FIRSTLINE设置为第一行,但只能在子shell中使用,因此以后将无法使用)。解决方案:只需使用read -r line <filename
Gordon Davisson 2010年

5

只是echo源文件的第一个列表到目标文件中。

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

3
为此head -n 1 source.txt > target.txt将完全相同。
悠悠球

4

该问题并未询问哪个是最快的,但要添加到sed答案中,-n'1p'的性能很差,因为仍在大文件上扫描模式空间。出于好奇,我发现sed几乎胜过了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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.