【问题标题】:To print FileName and selected rows:要打印 FileName 和选定的行:
【发布时间】:2015-12-12 07:38:53
【问题描述】:

想要打印目录中所有文件的前 2 行以及文件名。 都是 .csv 扩展文件。该目录中有大约 100 个文件。

sample_jan.csv

10,Jan,100
30,Jan,300
50,Jan,500

sample_feb.csv

10,Feb,200
20,Feb,400
40,Feb,800
60,Feb,1200

预期输出:

Filename:sample_jan.csv
10,Jan,100
30,Jan,300

Filename:sample_feb.csv
10,Feb,200
20,Feb,400

尝试为单个文件列出 2 行,如下所示,但不知道如何循环访问所有文件。

cat sample_jan.csv | head -2 >>output.csv
cat sample_feb.csv | head -2 >>output.csv

cat *.csv | head -2 >output.csv

寻找您的建议,没有 perl 和 python。

【问题讨论】:

    标签: unix awk


    【解决方案1】:

    使用awk

    $ awk 'FNR==1{print "Filename:" FILENAME}FNR<3' *.csv
    Filename:sample_jan.csv
    10,Jan,100
    30,Jan,300
    Filename:sample_feb.csv
    10,Feb,200
    20,Feb,400
    

    如果你有 GNU awk 并且你的文件很大,那么这可能是一个选择:

    $ gawk 'FNR==1{print "Filename:" FILENAME}FNR>2{nextfile}1' *.csv
    Filename:sample_jan.csv
    10,Jan,100
    30,Jan,300
    Filename:sample_feb.csv
    10,Feb,200
    20,Feb,400
    

    【讨论】:

    • Jaypal,如果源输入是 *.gz (gunzip) 文件,则 FileName 不会打印,例如当我尝试时,zcat sample_jan.csv.gz | awk 'FNR==1{print "Filename:" FILENAME} FNR Output.txt
    • 得到这个输出:文件名:- 10,Jan,100 30,Jan,300 文件名出现的地方是空白
    • @AVN FILENAME 从管道读取时不会填充变量。
    • Jaypal,请建议如何为 Gunzip 源文件捕获文件名
    【解决方案2】:

    在 awk 中:

    awk '
      FNR == 1  {if(NR!=1)print""; printf("Filename:%s\n", FILENAME)}
      FNR < 3
    ' *.csv
    

    说明

    回想一下:

    • 记录默认为行
    • NR 从 1 开始计数记录并且不会在文件之间重置
    • FNR 从 1 开始对记录进行计数,并将每个文件重置为 1。

    脚本:

    FNR == 1 {  # If it's the first record of the current file then:
        if (NR != 1) # If it's NOT the first record of all files
            print "";  #   then print an empty line
        printf("Filename:%s\n", FILENAME) # Print the filename
    }
    
    # If record number of current file is < 3 then
    # perform default action (print the record).
    FNR < 3
    

    如果您有太多文件无法在命令行中容纳(*.csv 扩展后),那么您可以试试这个:

    find -name '*.csv' -execdir awk '
      FNR == 1 {
        file = FILENAME
        sub(/^\.\//, "", file)
        printf("\nFilename:%s\n", file)
      }
      FNR < 3
    ' '{}' +
    

    上面的 find 命令将执行 awk,其中包含尽可能多的文件名列表,以适合命令行('{}' + 被此列表替换),根据需要运行 awk 多次,但次数最少。

    awk 脚本中的替换会在文件名打印之前从文件名的前面去除./

    【讨论】:

    • 您可能需要添加一些解释。
    【解决方案3】:
    For file in *
    do
        echo "Filename:$file" >> output.csv
        head -2 $file >> output.csv
        echo
    done
    

    无需cat 并将文件通过管道传输到头部。它可以将文件名作为参数。

    【讨论】:

      【解决方案4】:

      如果您不关心标签Filename:,您可以:

      head -n2 * > output.csv
      

      【讨论】:

        【解决方案5】:

        您可以像这样循环查看目录中的所有.csv 文件:

        for f in *.csv; do YOUR_COMMAND; done

        这应该与您的命令相结合:

        for f in *.csv; do cat "$f" | head -2 &gt;&gt;output.csv ; done

        (未经测试 - 仅供参考)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-08
          • 2014-02-23
          • 1970-01-01
          • 1970-01-01
          • 2016-06-30
          • 2014-12-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多