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
部分之外,否则每次迭代都会覆盖文件。