【问题标题】:How do I read the Nth line of a file and print it to a new file? [duplicate]如何读取文件的第 N 行并将其打印到新文件中? [复制]
【发布时间】:2011-11-03 14:31:55
【问题描述】:

我有一个名为 foo 的文件夹。 Foo 有一些其他文件夹,其中可能有子文件夹和文本文件。我想找到以名称 year 开头的每个文件,并读取它的第 N 行并将其打印到一个新文件中。例如 foo 有一个名为 year1 的文件,子文件夹有一个名为 year2、year3 等的文件。程序会将 year1 的第一行打印到名为 writeout 的文件中,然后将 year2 的第二行打印到文件 writeout 等。

我也不太明白如何为文件执行 for 循环。

到目前为止我有:

#!/bin/bash

for year* in ~/foo
do
  Here I tried writing some code using the sed command but I can't think of something       else.
done

我还在终端中收到一条消息,上面写着“年份*”不是有效的标识符。 有什么想法吗?

【问题讨论】:

  • 您能否接受以下答案之一,因为我相信他们为这个问题提供了足够的信息?

标签: bash shell unix


【解决方案1】:

给你

sed ${index}'q;d' ${input_file} > ${output_file}

【讨论】:

    【解决方案2】:

    这是一种方法:

    awk "NR==$YEAR" $file
    

    【讨论】:

    • 我收到消息:意外的换行符或字符串结尾。
    • 那么 $YEAR 是一个空字符串或者不是一个数字...
    【解决方案3】:

    Sed 可以帮助您。

    回想一下,sed 通常会处理文件中的所有行并打印文件中的每一行。

    您可以关闭该功能,并通过匹配模式或行号让 sed 仅打印感兴趣的行。

    所以,要打印文件 2 的第二行,你可以说

    sed -n '2p' file2 > newFile2
    

    要打印第 2 行然后停止处理,请添加 q(用于退出)命令(您还需要大括号将 2 个命令组合在一起),即

    sed -n '2{p;q;}' file2 > newFile2
    

    (如果您正在处理大文件,这可能会非常节省时间)。

    为了更通用,您可以将数字更改为将保存数字的变量,即

      lineNo=3
      sed -n "${lineNo}{p;q;}" file3 > newFile3
    

    如果您希望将所有切片行放入 1 个文件中,请使用 shell 'append-redirection',即

     for lineNo in 1 2 3 4 5 ; do
         sed -n  "${lineNo}{p;q;}" file${lineNo} >> aggregateFile
     done
    

    其他帖子,使用find ... 的结果来驱动您的文件列表,是一个很好的方法。

    我希望这会有所帮助。

    【讨论】:

    • 分组语法在 GNU sed 中有效。
    • @glennjackman :不确定你的观点。分组语法也适用于 AIX 和 solaris 上的 sed,据我所知和相信,这是 sed 原始设计的一部分。感谢您的反馈:-)
    • 如果你喜欢 Python 而不是 sed,你可以这样做...python -c "import sys; print(sys.stdin.readlines()[int(sys.argv[1])-1]).strip()" <n>(或者当然为那件大事定义一个别名)
    【解决方案4】:

    使用find 定位您想要的文件,然后使用sed 提取您想要的文件:

    find foo -type f -name year* |
    while read file; do
        line=$(echo $file | sed 's/.*year\([0-9]*\)$/\1/')
        sed -n -e "$line {p; q}" $file
    done
    

    这种方法:

    • 使用find 生成名称以字符串“year”开头的文件列表。
    • 将文件列表通过管道传递到while 循环以避免长命令行
    • 使用sed 从文件名中提取所需的行号
    • 使用sed 仅打印所需的行,然后立即退出。 (您可以省略q,而只写${line}p,这会起作用,但$file 的效率可能较低。此外,q 的所有版本都可能不完全支持sed。)

    但它不适用于名称中带有空格的文件。

    【讨论】:

    • 我收到消息说:sed: -e expression #1, char 7: unknown command: `k'
    • 你能粘贴bin之后的命令输出,运行“set -x”来启用调试吗?
    • 抱歉,我不明白我要做什么。我是初学者。
    • 首先输入“set -x”。然后像上面一样运行命令。然后选择文本并转到 pastebin.com 并粘贴错误。然后在此处发布 URL 作为评论。
    • +1,但要注意'{p; q}' 不适用于所有版本的 sed。
    【解决方案5】:

    如果您提供 2 个参数,则始终有效的最佳方法:

    $ touch myfile
    $ touch mycommand
    $ chmod +x mycommand
    $ touch yearfiles
    $ find / -type f -name year* >> yearfiles
    $ nano mycommand
    $ touch foo
    

    输入这个:

    #/bin/bash
    head -n $1 $2 >> myfile
    less -n 1 myfile >> foo
    

    使用^Xy,回车保存。然后运行我的命令:

    $ ./mycommand 2 yearfiles
    $ cat foo
    year2
    

    假设您的 year 文件是:

    year1, year2, year3
    

    另外,现在你已经设置好了,从现在开始你只需要使用$ ./mycommand LINENUMBER FILENAME

    【讨论】:

      【解决方案6】:

      您的任务有两个子任务:查找所有年份文件的名称,然后提取第 N 行。考虑以下脚本:

      for file in `find foo -name 'year*'`; do
           YEAR=`echo $file | sed -e 's/.*year\([0-9]*\)$/\1/'`
           head -n $YEAR $file | tail -n 1
      done
      

      find 调用会在 foo 目录中为您找到匹配的文件。第二行仅从文件名中提取文件名末尾的数字。然后第三行从文件中提取前 N 行,仅保留前 N 行中的最后一行(读取:仅第 N 行)。

      【讨论】:

      • 我应该在我的屏幕上看到什么吗?因为我只得到一个空行。
      【解决方案7】:
      1.time head -5 emp.lst tail -1
      It has taken time for execution is
      real 0m0.004s
      user 0m0.001s
      sys 0m0.001s
      
      or
      
      2.awk 'NR==5' emp.lst
      It has taken time for execution is
      real 0m0.003s
      user 0m0.000s
      sys 0m0.002s
      
      or 
      
      3.sed -n '5p' emp.lst
      It has taken time for execution is
      real 0m0.001s
      user 0m0.000s
      sys 0m0.001s
      
      or 
      
      4.using some cute trick we can get this with cut command
      cut -d “
      “ -f 5 emp.lst
      # after -d press enter ,it means delimiter is newline
      It has taken time for execution is
      real 0m0.001s
      

      【讨论】:

      • 虽然您的回答可能会解决问题,但最好能说明问题所在以及您的回答如何解决问题。这是进一步改进这个和未来答案的建议。
      • 你能详细说明你的答案是如何工作和有帮助的吗?
      猜你喜欢
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多