bash脚本读取每个文件中的行,将特定值复制到新文件

bash脚本读取每个文件中的行,将特定值复制到新文件,bash,Bash,我想写一个脚本来帮助我完成我的工作。 问题:我在一个目录中有许多包含数据的文件,我需要从每个文件中复制一个新文件中的特定值。 数据文件可以如下所示: Name abc $desV0 Start MJD56669 opCMS v2 End MJD56670 opCMS v2 ... valueX 0.0456 RV_gB ... valueY 12063.23434 RV_gA ... 脚本应该做的是将valueX和以下值以及valueY和

我想写一个脚本来帮助我完成我的工作。 问题:我在一个目录中有许多包含数据的文件,我需要从每个文件中复制一个新文件中的特定值。 数据文件可以如下所示:

Name   abc   $desV0
Start   MJD56669   opCMS v2
End   MJD56670   opCMS v2
...
valueX   0.0456   RV_gB
...
valueY   12063.23434 RV_gA
...          
脚本应该做的是将valueX和以下值以及valueY和以下值复制到一行中的新文件中。该行中的外接程序是源数据文件的名称。此外,valueY的值应仅包含点之前的所有内容。 结果应该如下所示:

valueX 0.0456 valueY 12063 name_of_sourcefile
到目前为止,我:

for file in $(find -maxdepth 0 -type f -name *.wt); do
    for line in $(cat $file | grep -F vb); do
        cp $line >> file_done
    done
done
但这根本不起作用。我也不知道如何在新文件的一行中获取数据。
有人能帮我吗?

我认为使用awk可以大大简化脚本:

awk '/valueX/{x=$2}/valueY/{print "valueX",x,"valueY",$2,FILENAME}' *.wt > file_done
这将遍历当前目录中的每个文件。匹配“valueX”时,该值将保存到变量
x
。当匹配“valueY”时,将打印该行

这假设包含“valueX”的行始终位于包含“valueY”的行之前。如果这不是一个有效的假设,那么脚本可以很容易地更改

要仅打印“valueY”的整数部分,可以使用
printf
而不是
print

awk '/valueX/{x=$2}/valueY/{printf "valueX %s valueY %d %s\n",x,$2,FILENAME}' *.wt > file_done
%d
是整数的格式说明符

如果您的需求更复杂,并且需要使用
查找
,则应使用
-exec
,而不是循环查看结果,以避免出现文件名不正确的问题:

find -maxdepth 1 -iname "5*.par" ! -iname "*_*" -exec \
awk '/valueX/{x=$2}/valueY/{printf "valueX %s valueY %d %s\n",x,$2,"{}"}' '{}' \; > file_done

请尝试以下操作:

egrep "valueX|valueY" *.wt | awk -vRD="\n" -vORS=" " -F':| ' '{if (NR%2==0) {print $2, $3, $1} else {print $2, $3}}' > $file.new.txt

不要打架。我真的很感谢你的帮助和快速的回答。 这是我的最终解决方案,我认为:

#!/bin/bash

for file in $(find * -maxdepth 1 -iname "5*.par" ! -iname "*_*"); do
awk '/TASC/{x=$2}/START/{printf "TASC %s MJD %d %s",x,$2, FILENAME}' $file > mjd_vs_tasc
done

再次非常感谢你们。

啊,太好了。我喜欢世界各地的极客,他们能在几分钟内找到解决方案,即使在“插入长时间”后我也会失败最后一件事:valueY不应该复制为完整的数字,而应该只复制前导的数字。i、 e.10023.5879应仅为10023。这可能吗?@感觉我再次编辑了我的答案,以展示一种比使用
for
循环和
find
更好的方法。我很高兴您的问题得到了解决。如果您使用了我的答案(或对其进行了非常轻微的修改),您应该接受它,而不是发布您自己的答案。顺便说一下,如果要使用循环,应该将重定向
>mjd_vs_tasc
移动到循环的
done
部分之外,否则每次迭代都会覆盖文件。