【问题标题】:How to get the first line of a file in a bash script?如何在 bash 脚本中获取文件的第一行?
【发布时间】:2010-03-13 18:56:13
【问题描述】:

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

【问题讨论】:

    标签: bash


    【解决方案1】:

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

    line=$(head -n 1 filename)
    

    【讨论】:

    • read 方法的开销要大得多。 $() 分叉出一个子外壳,并且使用外部命令(any 外部命令)意味着您正在调用 execve(),调用链接器和加载器(如果它使用共享库,这通常是案例)等。
    • 它可能会更短:line="$(head -1 FILENAME)"
    • 还有:line=`head -1 FILENAME`
    • head... 周围的反引号是否像$() 那样打开子shell?。
    • @JaimeHablutzel 是的,它们是一回事,尽管我个人发现$() 语法更容易看到,并且重视清晰而不是绝对简洁。 gnu.org/software/bash/manual/html_node/…
    【解决方案2】:

    要使用 bash 读取第一行,请使用 read 语句。例如

    read -r firstline<file
    

    firstline 将是您的变量(无需分配给另一个)

    【讨论】:

    • @sorin, cat ... | read VAR 在大多数 shell 中都会失败(据我所知,除了zsh),因为管道中的每个组件都将在单独的子 shell 中运行。这意味着$VAR 将设置在子shell 中(一旦管道完成执行就不再存在),而不是在调用shell 中。您可以使用 read VAR &lt;&lt;EOF\n$(cat ...)\nEOF 解决此问题(其中每个 \n 是一个换行符)。
    • @sorin, cat 是纯开销;无论如何,read -r var &lt;filecat file | read 更有效,即使 if 后者并没有因为BashFAQ #24 中描述的原因而失败。
    • ...如果你的工作比cat 更复杂,那么read -r var &lt; &lt;(otherprog ...)
    【解决方案3】:

    这就足够了并将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)


    当我们用seq 10 输入read 时看一个示例,即从1 到10 的数字序列:

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

    【讨论】:

    • sed '1!d;q'(或sed -n '1p;q')将模仿您的awk 逻辑并阻止进一步读取文件。因为我们只想要第一行,所以我们可以选择用sed qawk '1;{exit}' 甚至grep -m1 ^ 作弊(代码更少,基本逻辑相同)。 (这不是对反对票查询的回复。)
    • @AdamKatz 这是一组非常好的方法,谢谢!我发现带有grep 的那个非常聪明。我们当然也可以说head -n 1 file
    • 是的,head -n1 会更快(加载更小的二进制文件),read 会最快(无需加载二进制文件,这是内置的)。我特别喜欢grep -m1 --color .,因为我只打印第一行,因为它也会为行着色,非常适合表格标题。
    【解决方案4】:
    line=$(head -1 file)
    

    会正常工作。 (如先前的答案)。但是

    line=$(read -r FIRSTLINE < filename)
    

    会稍微快一点,因为read 是一个内置的 bash 命令。

    【讨论】:

    • 第二种方法不能像所写的那样工作,因为read 不打印任何东西(所以line 结束为空白),并且还在子shell 中执行(所以FIRSTLINE 设置为第一行,但仅在子shell中,因此之后不可用)。解决方案:只需使用read -r line &lt;filename
    • line=$(read -r
    【解决方案5】:

    只需将echo 的第一个列表源文件放入您的目标文件中。

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

    【讨论】:

    • head -n 1 source.txt &gt; target.txt 将完成完全相同的工作。
    【解决方案6】:

    这个问题没有问哪个最快,但要添加到 sed 答案中,-n '1p' 性能很差,因为仍然在大文件上扫描模式空间。出于好奇,我发现 'head' 险胜 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
    

    【讨论】:

      【解决方案7】:

      只读取文件的第一行并将其存储到变量中:

      read var < file
      
      echo $var # print only the first line of 'file'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-06
        • 2010-09-25
        • 2015-12-01
        • 1970-01-01
        • 2017-12-20
        • 1970-01-01
        • 2010-10-28
        • 2019-08-13
        相关资源
        最近更新 更多