【问题标题】:Prepending part of a filename to a .csv file using bash/sed使用 bash/sed 将文件名的一部分附加到 .csv 文件
【发布时间】:2017-08-30 09:26:21
【问题描述】:

我在一个目录中有几个文件是这样命名的;

1_38OE983729JKHKJV.csv

一个整数,后跟一个 ID(整数和 ID 都是唯一的)。

我需要为文件夹中的每个文件在文件的每一行添加此 ID,以准备将文件导入数据库(并丢弃文件名的整数部分)。该文件的内容如下所示:

BW;20015;11,45;0,49;41;174856;4103399
BA;25340;11,41;0,55;40;222161;4599779
BB;800;7,58;0,33;42;10559;239887
HE;6301;9,11;0,39;40;69191;1614302
.
.
.
Total;112613;9,33;0,43;40;1207387;25897426

最终结果应该是这样的:

38OE983729JKHKJV;BW;20015;11,45;0,49;41;174856;4103399
38OE983729JKHKJV;BA;25340;11,41;0,55;40;222161;4599779
38OE983729JKHKJV;BB;800;7,58;0,33;42;10559;239887
38OE983729JKHKJV;HE;6301;9,11;0,39;40;69191;1614302
.
.
.
38OE983729JKHKJV;Total;112613;9,33;0,43;40;1207387;25897426

感谢您的帮助!

编辑:为了清楚起见,拼写和词汇

【问题讨论】:

    标签: bash csv sed


    【解决方案1】:

    循环使用for的文件,使用参数扩展提取id。

    #!/bin/bash
    for csv in *.csv ; do
        prefix=${csv%_*}
        id=${csv#*_}
        id=${id%.csv}
        sed -i~ "s/^/$id;/" "$csv"
    done
    

    如果 ID 可以包含下划线,您可能需要更加小心扩展。

    【讨论】:

    • 它给了我这个错误:我的输入:sh addId.sh :command not found 'ddId.sh: line 3: syntax error near unexpected token do 'ddId.sh: line 3: for csv in *.csv ;做
    • 不要使用sh调用bash脚本。
    • 我的错,谢谢!我习惯使用 macOS,其中 sh 实际上调用 bash 而不是标准的 bourne shell。生活和学习!
    【解决方案2】:

    使用 awk 工具:

    for f in *csv; do awk '{ fn=FILENAME; $0=substr(fn,index(fn,"_")+1,length(fn)-6)";"$0 }1' "$f" > tmp && mv tmp "$f"; done
    
    • fn=FILENAME - 文件名

    【讨论】:

      【解决方案3】:

      在单个 awk 中也尝试跟随,它也会处理在此操作期间打开的文件数,这样我们就可以避免最大打开文件数的错误。

      awk 'FNR==1{close(val);val=FILENAME;split(FILENAME,a,"_");sub(/\..*/,"",a[2])} {print a[2]","$0}' *.csv
      

      【讨论】:

      • 我必须如何执行这个?这必须在同一个目录中吗?
      • @Tassanara:尝试在终端上运行,它只会打印行,如果您需要输出到单个输出文件中,那么您可以在命令的最后执行 > output_file,让我知道它是怎么回事那么。
      • @Tassanara:很高兴它帮助了你。
      • 这不适用于多个文件。例如close(val) 试图关闭之前的FILENAME 值,但close() 仅适用于由于重定向而打开的文件(例如print > filegetline < file),而不是作为常规工作循环的一部分。无论如何,仅打印到标准输出显然一次只能处理一个文件,所以不要尝试*.csv。如果要在 FILENAME 上使用 split(),为什么不在 _. 上拆分它,而不是在 _ 上拆分它,然后在 . 上拆分它? split() 的第三个参数是一个正则表达式,顺便说一句不是字符串。最后,所需的分隔符是;,而不是,;。
      【解决方案4】:

      使用 GNU awk 进行就地编辑和 gensub() 您只需要:

      awk -i inplace '{print gensub(/.*_(.*)\..*/,"\\1;",1,FILENAME) $0}' *.csv
      

      没有 shell 循环或其他任何必要的东西,只有那个命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-27
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        • 2021-07-22
        • 2019-08-01
        • 1970-01-01
        • 2018-02-22
        相关资源
        最近更新 更多