如何在bash脚本中获取文件的第一行?
我必须在文件的第一行输入一个bash变量。我想这是通过grep命令实现的,但这是限制行数的任何方法吗?如何在bash脚本中获取文件的第一行?,bash,Bash,我必须在文件的第一行输入一个bash变量。我想这是通过grep命令实现的,但这是限制行数的任何方法吗?head从文件中提取第一行,并且-n参数可用于指定应提取多少行: line=$(head -n 1 filename) 会很好的。(如前面的回答)。但是 line=$(read-r FIRSTLINE
head
从文件中提取第一行,并且-n
参数可用于指定应提取多少行:
line=$(head -n 1 filename)
会很好的。(如前面的回答)。但是
line=$(read-r FIRSTLINE
由于
read
是一个内置的bash命令,速度会稍微快一些。要使用bash读取第一行,请使用read
语句。乙二醇
read -r firstline<file
read-r firstline这就足够了,并将文件名的第一行存储在变量$line
中:
read -r line < filename
要存储行本身,请使用var=$(命令)
语法。在本例中,line=$(awk'NR==1{print;exit}'文件)
甚至sed
:
sed -n '1p' file
使用等效的line=$(sed-n'1p'文件)
当我们将read
与seq 10
一起输入时,可以看到一个示例,即从1到10的数字序列:
$ read -r line < <(seq 10)
$ echo "$line"
1
$ line=$(awk 'NR==1 {print; exit}' <(seq 10))
$ echo "$line"
1
$read-r line<这个问题没有问哪一个最快,但要添加到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
只需将源文件的第一个列表回显到目标文件中即可
echo $(head -n 1 source.txt) > target.txt
第二个方法不能像编写的那样工作,因为read
不打印任何内容(因此行
最后为空),并且也在子shell中执行(因此FIRSTLINE
设置为第一行,但仅在子shell中,因此之后不可用)。解决方案:只要使用read-r line line=$(read-rsed'1!d;q'
(或者sed-n'1p;q'
)将模拟您的awk
逻辑并阻止进一步读取文件。因为我们只需要第一行,我们可以使用sed q
或awk'1;{exit}'
甚至grep-m1^
(代码更少,基本逻辑相同)。(这不是对否决票查询的答复。)@AdamKatz这是一套非常好的方法,谢谢!我发现带有grep
的方法非常聪明。我们当然也可以说head-n1文件
。是的,head-n1
将更快(加载的二进制文件更小),而读取的速度将最快(没有二进制文件加载,这是一个内置的)。我特别喜欢grep-m1--color.
当我刚打印第一行时,因为它也会给这行上色,使它适合表格标题。对于这一行,head-n1 source.txt>target.txt
将实现完全相同的效果。@sorin,cat…| read VAR
在大多数shell中都会失败(据我所知,除了zsh
),因为管道中的每个组件都将在单独的子shell中运行。这意味着$VAR
将在子shell中设置(一旦管道完成执行,子shell就不再存在)而不是在调用shell中。您可以通过read-VAR@sorin解决这个问题,cat
是纯开销;read-r-VAR效率更高……如果您运行的是比cat
更复杂的东西,那么read-r-VAR<的开销比read
方法要大得多。$()
派生出一个子shell,使用外部命令(任何外部命令)意味着您正在调用execve()
,调用链接器和加载程序(如果它使用共享库,通常是这样),等等。它可能更短:行=“$(head-1 FILENAME)”
还有:行=`head-1 FILENAME`
是否像$()
一样,围绕头的反勾号打开一个子shell?@JaimeHablutzel是的,它们是一样的,尽管我个人发现$()
语法更容易看到,并且重视清晰而不是绝对简洁。
$ read -r line < <(seq 10)
$ echo "$line"
1
$ line=$(awk 'NR==1 {print; exit}' <(seq 10))
$ echo "$line"
1
# 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
echo $(head -n 1 source.txt) > target.txt