搜索子文件夹中的多个文件并仅打印数值

时间:2014-10-17 22:09:17

标签: bash awk sed grep cut

我对使用TWO模式在子文件夹中搜索多个文件的内联操作有疑问,并且只打印数值。

示例:

当前目录:$HOME/work/A/(运行脚本的位置)

包含数据的子文件夹:$HOME/work/A/trial1, trial2, trial3..

输入(每个数据文件):例如。 trial1/trial1.out

[text]
..
cutoff = 100
..
[text] 
..
! total energy= -23.4387 Ry
.. 

需要输出:/A/totalenergy.txt

100   -23.4387
110   -23.2523
120   -24.0134
...

我最初的计划是使用' grep'搜索每个文件并匹配模式' cutoff ='和'! '找到两条所需的线,并只打印截止数和能量数。

然而,到目前为止,我能做的只是搜索1种模式,'!总能量' (更重要的是),并使用grep | tr | cut > file来获取能量。

grep -e "\!" */*.out | tr -s ' ' | cut -f5 -d' ' >totalenergy.txt

基本上,我在寻找'!',搜索所有子文件夹以获取* .out,修剪多个空格,并仅保留数字字段

包含'!的行总能量'使用grep之后看起来像这样

60/C.scf_60.out:!    total energy              =     -22.78085574 Ry

所以,如果我能以某种方式从这一行获得第一个号码,加上我拥有的号码,我也可以实现我的目标:

60  -22.78085574

我试图用一行命令来做这件事。

谢谢!

1 个答案:

答案 0 :(得分:3)

sed -rn -e 's/cutoff[ =]+([0-9]+)/\1/p' -e 's/.*total energy[= ]+([0-9.-]+).*/\1:/p' */*.out | tr '\n:' ' \n'

说明:

sed -rn -e <cmd1> -e <cmd2> */*.out

我已使用sed代替grep因为我不得不使用标记(我选择:)来分隔每个寄存器( cutoff < / em> total_energy )。

sed选项

-r # short form of --regexp-extended

需要与我使用的sintax相匹配。特别([0-9.-]+) - &gt;我没有必要逃避括号,我可以毫无问题地过滤.-

-n # short option of --quiet or --silent

除非我们明确要求这样做(使用标记p

,否则会禁用模式打印
-e # short of --expression

用于组合多个命令

模式和替换

cutoff[ =]+([0-9]+)/\1
.*total energy[= ]+([0-9.-]+).*/\1:

我只是保存 \1中我需要的值。

请注意,我在总能量匹配的值之后添加了:个字符。正如我所说,它是帮助我将寄存器与tr分开。

sed flag

's/../../p'

我已使用p打印模式,因为我已使用-n禁用了打印功能。它需要丢弃没有匹配的所有行。


tr '\n:' ' \n'

由于sed输出了不同行中的每个值,我使用了一个标记(:)来知道在哪里写一个换行符(\n)。

字符替换

tr正在将SET1('\n:')中的字符转换为SET2(' \n')中的字符。翻译将取代SET1中的每个字符,SET2中的每个字符位于相同的位置:

# \n  ->  " " (space)
# :   ->  \n

注意:您可能希望再次管道(| tr -s ' ')来清理输出


格式化输出

的另一种方法

更严格的打印结果方法是再次sed,因此输出完全符合您的要求:

sed -rn -e 's/cutoff[ =]+([0-9]+)/\1/p' -e 's/.*total energy[= ]+([0-9.-]+).*/\1:/p' */*.out | tr '\n' ' ' | sed -r "s/([^:]+):[ ]*/\1\n/g"

请注意,util第一个|命令与上面的命令完全相同。

tr '\n' ' '

它只是用空格替换换行符。

sed -r "s/([^:]+):[ ]*/\1\n/g"

保存字符串直到:并打印后跟换行符