我对使用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
我试图用一行命令来做这件事。
谢谢!
答案 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 )。
-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
分开。
'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"
将保存字符串直到:
并打印后跟换行符