【问题标题】:Using sed to dynamically generate a file name使用sed动态生成文件名
【发布时间】:2009-10-08 22:23:22
【问题描述】:

我有一个 CSV 文件,我想根据文件中的字段进行拆分。本质上,可以有两个品牌,GVA 和 HBVL。在将文件导入数据库之前,我想将文件拆分为每个品牌的文件。

CSV 文件示例

"D509379D5055821451C3695A3752DCCD",'1900-01-01 01:00:00',"M","1740","GVA",'2009-07-01 13:25:00',0
"159A58BE41012787D531C7157F688D86",'1900-01-01 00:00:00',"V","1880","GVA",'2008-06-06 11:21:00',0
"D0BB5C058794BBE4478DDA536D1E4872",'1900-01-01 00:00:00',"M","9270","GVA",'2007-09-18 13:21:00',0
"BCC7096803E5E60E05DC12FB9951E0CF",'1900-01-01 00:00:00',"M","3500","HBVL",'2007-09-18 13:21:00',1
"7F85FCE6F13775A8A3054E3438B81599",'1900-01-01 00:00:00',"M","3970","HBVL",'2007-09-18 13:20:00',0

部分问题在于文件的大小。大约39mb。我最初的尝试是这样的:

while read line ; do

    name=`echo $line | sed -n 's/\(.*\)"\(GVA\|HBVL\)",\(.*\)$/\2/ p' | tr [:upper:] [:lower:] `
    info=`echo $line | sed -n 's/\(.*\)"\(GVA\|HBVL\)",\(.*\)$/\1\3/ p'`

    echo "${info}" >> ${BASEDIR}/${today}/${name}.txt

done < ${file}

大约 2.5 小时后,仅处理了大约 1/2 的文件。我有另一个文件,其大小可能高达 250 mb,我无法想象这需要多长时间。

我想做的是从行中提取品牌并将行写入以品牌命名的文件。我可以删除品牌,但我现在不知道如何使用它来创建文件。我已经开始使用 sed,但如果更合适的话,我不会使用另一种语言。

【问题讨论】:

  • 不要使用 bash 的 while read 行结构来读取大文件,尤其是在循环中同时使用 sed 或 tr 等外部命令时。它会大大减慢您的处理速度。使用内部解析文件的工具,例如 awk

标签: shell sed


【解决方案1】:

每行包含多个命令的原始 while 循环是 DIRE!

sed -e '/"GVA"/w gva.file' -e '/"HBVL"/w hbvl.file' -n $file

sed 脚本说:

  • 将匹配 GVA 标签的行写入 gva.file
  • 将匹配 HBVL 标记的行写入 hbvl.file
  • 并且不要打印任何其他内容 ('-n')

请注意,不同版本的sed 可以处理不同数量的辅助文件。如果您一次需要超过 20 个输出文件,您可能需要查看其他技术(但测试您机器上的限制)。如果文件经过排序,所有 GVA 记录一起出现,然后是所有 HBVL 记录,您可以考虑使用csplit。或者,像 Perl 这样的脚本语言可以处理更多。如果您超过了进程允许的文件描述符数量,则很难在一次通过数据文件时进行拆分。

【讨论】:

  • 注意:您仍然可以使用此技术剥离品牌字段:sed -n -e '/"GVA"/ s/\(.*\)"\(GVA\)",\(.*\)$/\1\3/ w gva.file' -e '...
  • 我知道我想多了。我真的不应该在这么晚的时候尝试解决这样的问题。
【解决方案2】:
grep '"GVA"' $file >GVA.txt
grep '"HVBL"' $file >HVBL.txt

【讨论】:

  • 这可能不是最快的解决方案,但它可能已经足够接近了。当然也很容易理解。
  • 如果文件很大,那么使用 grep 对文件进行 2 次迭代是没有意义的。最好先浏览一下文件并获得所需的东西。
【解决方案3】:
# awk -F"," '{o=$5;gsub(/\"/,"",o);print $0 > o}' OFS="," file
# more GVA
"D509379D5055821451C3695A3752DCCD",'1900-01-01 01:00:00',"M","1740","GVA",'2009-07-01 13:25:00',0
"159A58BE41012787D531C7157F688D86",'1900-01-01 00:00:00',"V","1880","GVA",'2008-06-06 11:21:00',0
"D0BB5C058794BBE4478DDA536D1E4872",'1900-01-01 00:00:00',"M","9270","GVA",'2007-09-18 13:21:00',0
# more HBVL
"BCC7096803E5E60E05DC12FB9951E0CF",'1900-01-01 00:00:00',"M","3500","HBVL",'2007-09-18 13:21:00',1
"7F85FCE6F13775A8A3054E3438B81599",'1900-01-01 00:00:00',"M","3970","HBVL",'2007-09-18 13:20:00',0

【讨论】:

    猜你喜欢
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    相关资源
    最近更新 更多