【问题标题】:printing data column wise using grep or awk使用 grep 或 awk 打印数据列
【发布时间】:2013-07-04 11:46:01
【问题描述】:

我有两个文件说(file1.dat, file2.dat)

file1.dat contains a line similar to
     STR       KAPPA2=0 RMAXS=4.2 NDIMIN=0 NOCALC=F IALPHA=0
file2.dat contains 
     class Fe   convergency of s-channel=   0.347E-04
     class Sr   convergency of s-channel=   0.289E-04
     class Bi   convergency of s-channel=   0.111E-04
     class Pt   convergency of s-channel=   0.900E-04

我想获取RMAXS (4.2)convergency 的值,然后存储这些值 文件中的值 (say plot), column wise

4.2    0.347E-04
4.2    0.289E-04
4.2    0.111E-04
4.2    0.900E-04

我可以获取单个值(使用 grepawk)但不知道如何将它们存储在 以上格式。

Also is there a way to print the shell variables like `$HOME` or
`$PWD` as the third column in the file (plot).

【问题讨论】:

  • 文件间链接记录的关键是什么?
  • @fedorqui:显然这不是join 的问题。我假设 file1.datfile2.dat 是单个实验的输出,整个过程将运行一系列实验,覆盖相同的文件并从每次运行中提取值。

标签: awk grep


【解决方案1】:

这是一个简单的 Awk 解决方案。

awk -v h="$HOME" '# From file1.dat, read RMAXS value into r
    NR==FNR { if (sub(/.*RMAXS=/,"")) { sub(/ .*/,""); r = $0; } next }
    # From file2.dat, print final field along with r and h
    /convergency of s-channel=/ { print r, $NF, h }' file1.dat file2.dat >plot

-v var=value 选项允许您从命令行分配任意变量。这里,我们用它来设置h为环境变量HOME的值。

NR 变量跟踪行号,FNR 变量跟踪当前文件中的行号。所以NR==FNR 在处理第一个文件时。如果找到RMAXS=,则提取该值并将其分配给r。如果文件中有其他行,则直接跳过。

如果我们失败了,我们在第二个文件中;如果一行与convergency 正则表达式匹配,我们将打印最后一个字段(NF 计算行上的字段数,默认情况下以空格分隔)以及两个变量的值。

天真的尝试会使用一个 Awk 脚本从第一个文件中提取 RMAXS 的值,并将其作为变量提供给第二个 Awk 脚本。 NR==FNR 技巧允许我们在一个过程中完成所有操作,恕我直言,提高可读性(一旦您了解它的工作原理!)

【讨论】:

    【解决方案2】:

    根据您目前提供的信息。你需要的是echo and grep 看这个例子:

    我们有两个文件:f1 和 f2:

    kent$  head f*
    ==> f1 <==
    STR       KAPPA2=0 RMAXS=4.2 NDIMIN=0 NOCALC=F IALPHA=0
    
    ==> f2 <==
     class Sr   convergency of s-channel=   0.347E-04
    

    现在做这行:

    kent$  echo "$(grep -Po '(?<=RMAXS=)[^\s]*' f1)\t$(grep -Po 'channel=\s*\K[^\s]*' f2)\t$PWD" > f3
    

    检查新生成的文件,f3:

    kent$  cat f3
    4.2    0.347E-04    /tmp/test
    

    这 3 列是 &lt;tab&gt; 分隔的。您可以将其更改为 echo 行中的其他分隔符。

    【讨论】:

    • 我没有得到正确的输出,它的打印4.2\t0.347E-04\t/home/surender/garbage
    • \t 代表一个标签;如果您的 echo 不支持反斜杠转义,请将其替换为空格或文字制表符。
    【解决方案3】:

    我将假设 file1 中的每个 RMAXS 值对应于 file2 中的相应顺序收敛值,等等:

    paste <(grep -oP 'RMAXS=\K\S+' file1.dat) \
          <(grep -oP 'convergency[^=]+=\s*\K\S+' file2.dat) | 
    sed "$(printf 's#$#\t%s#' "$HOME")"
    

    &lt;(cmd arg ...) 语法称为process substitiution。您可以将命令管道视为其他命令可以读取或写入的文件。以下是指向pastesedgrepperl regular expressionsprintf 的文档链接

    【讨论】:

    • 这正是我想要的,但你能多解释一下语法或指出一些参考资料吗?我猜管道后面缺少一个反斜杠。
    • 在管道或&amp;&amp;|| 之后不需要反斜杠
    • 请在问题中说明您的所有要求,而不是散布在 cmets 中。
    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 2016-12-28
    • 2019-05-02
    相关资源
    最近更新 更多