从两个文件中提取某些数据并将它们放在一个文件中 - unix命令

时间:2016-01-27 16:36:25

标签: unix

我有一个目录“dir_ling”,其中包含一个文件列表:

file_i.cnf
file_i.cnf.out

表示0<我< Ñ

file_i.cnf的一个例子是

p cnf 8308 33032
c clauses-vars: 3.975927
1 -2 -3 0
-1 2 0
-1 3 0
4 -5 -3 0

file_i.cnf.out的一个例子是

[7.03] thread-stats node:0/1 thread:0/1 props:10733141 decs:23093 confs:22488 mem:3.03
[7.03] node-stats node:0/1 solved:1 res:10 props:10733141 decs:23093 confs:22488 mem:3.03 shared:0 filtered:0
[7.03] glob-stats nodes:1 threads:1 solved:1 res:10 rounds:8 time:7.00 mem:3.03 MB props:1533080.49 decs:3298.52 confs:3212.10 shared:0.00 imported:0.00 filtered:0.00 dropped:0.00

我需要一个带有输入“dir_ling”的命令,并输出文件dir_ling.timescv,其中该文件的每一行包含文件的名称,文件的名称为* .out的“time:”和“clauses-vars: “文件* .cnf;例如,dir_ling.timescv将包含

 file_1.cnf 7.00 3.975927
 file_2.cnf 8.00 4.909000
 .
 .
 .

我尝试使用此命令

 grep "glob-stats" $1/* | grep "solved:1" | tr : " " | cut -d " " -f 1,15 | sed 's/.*\///' | sed 's/\.out//' > solved-$1.times

用这个命令我得到了

 file_1.cnf 7.00
 file_2.cnf 8.00

我的问题是我怎样才能把“clauses-vars:”字段放在哪里?

2 个答案:

答案 0 :(得分:0)

使用类似

的内容循环文件
for f in file_*.cnf; do
   firstpart=$(grep "glob-stats" "${f}" | sed 's/.*time:\([^ ]*\).*/\1/')
   secondpart=$(grep "clauses-vars" ${f}.out | cut -d":" -f2)
   echo "$f ${firstpart}${secondpart}"
done

greps,cut和sed可以针对文件的有效性进行优化。在我的解决方案中,我做了一些假设:

  • cnf文件与glob-stats正好有1行 也许您想添加head -1
  • glog-stats的行有1个时间字段
    我对sed\(match_this\)使用了\1构造。
  • 包含ONE clauses-vars的行在正确位置有1 :

答案 1 :(得分:0)

管道可能不是最简单的方法。假设变量$nb包含文件的索引号,我可以打印一行:

echo file_$nb.cnf \
    $(sed -n '/glob-stats/s/.*time:\([.0-9]*\).*/\1/p' file_$nb.cnf.out) \
    $(sed -n 's/.*clauses-vars: //p' file_$nb.cnf)

然后你可以把它放在for循环中,让$nb遍历索引,并将输出重定向到一个文件。

详情:

  • -n sed的选项表示“除非明确要求,否则不要打印输出”。
  • 第一个sed命令在第一个文件(.cnf.out)中搜索包含glob-stats的行并对其执行替换,记住time:后面的数字并替换整条线路。然后打印(p)此替换的结果。
  • 第二个sed命令删除第二个文件中包含clauses-var:的行的开头,并打印(p)结果。
  • 两个sed命令都与命令替换一起使用(包含在$()中),以便命令被最终echo命令的输出替换。

使用paste和流程替换(paste <(echo $filename) <(sed …) <(sed …))可能会获得类似的东西