bash 脚本读取每个文件中的行,将特定值复制到新文件
bash script reading lines in every file copying specific values to newfile
我想写一个脚本来帮助我完成我的工作。
问题:我在一个包含数据的目录中有很多文件,我需要从每个文件中复制特定的值到一个新文件中。
数据文件看起来像这样:
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=}/valueY/{print "valueX",x,"valueY",,FILENAME}' *.wt > file_done
这会遍历当前目录中的每个文件。当匹配到"valueX"时,将值保存到变量x
中。当 "valueY" 匹配时,打印该行。
这假设包含 "valueX" 的行总是出现在包含 "valueY" 的行之前。如果这不是一个有效的假设,则可以轻松更改脚本。
要只打印 "valueY" 的整数部分,可以使用 printf
而不是 print
:
awk '/valueX/{x=}/valueY/{printf "valueX %s valueY %d %s\n",x,,FILENAME}' *.wt > file_done
%d
是整数的格式说明符。
如果您的要求更复杂并且您需要使用 find
,您应该使用 -exec
而不是循环遍历结果,以避免出现笨拙的文件名问题:
find -maxdepth 1 -iname "5*.par" ! -iname "*_*" -exec \
awk '/valueX/{x=}/valueY/{printf "valueX %s valueY %d %s\n",x,,"{}"}' '{}' \; > file_done
试试下面的方法:
egrep "valueX|valueY" *.wt | awk -vRD="\n" -vORS=" " -F':| ' '{if (NR%2==0) {print , , } else {print , }}' > $file.new.txt
不打。非常感谢您的帮助,尤其是快速的回答。
这是我认为的最终解决方案:
#!/bin/bash
for file in $(find * -maxdepth 1 -iname "5*.par" ! -iname "*_*"); do
awk '/TASC/{x=}/START/{printf "TASC %s MJD %d %s",x,, FILENAME}' $file > mjd_vs_tasc
done
再次感谢你们。
我想写一个脚本来帮助我完成我的工作。 问题:我在一个包含数据的目录中有很多文件,我需要从每个文件中复制特定的值到一个新文件中。 数据文件看起来像这样:
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=}/valueY/{print "valueX",x,"valueY",,FILENAME}' *.wt > file_done
这会遍历当前目录中的每个文件。当匹配到"valueX"时,将值保存到变量x
中。当 "valueY" 匹配时,打印该行。
这假设包含 "valueX" 的行总是出现在包含 "valueY" 的行之前。如果这不是一个有效的假设,则可以轻松更改脚本。
要只打印 "valueY" 的整数部分,可以使用 printf
而不是 print
:
awk '/valueX/{x=}/valueY/{printf "valueX %s valueY %d %s\n",x,,FILENAME}' *.wt > file_done
%d
是整数的格式说明符。
如果您的要求更复杂并且您需要使用 find
,您应该使用 -exec
而不是循环遍历结果,以避免出现笨拙的文件名问题:
find -maxdepth 1 -iname "5*.par" ! -iname "*_*" -exec \
awk '/valueX/{x=}/valueY/{printf "valueX %s valueY %d %s\n",x,,"{}"}' '{}' \; > file_done
试试下面的方法:
egrep "valueX|valueY" *.wt | awk -vRD="\n" -vORS=" " -F':| ' '{if (NR%2==0) {print , , } else {print , }}' > $file.new.txt
不打。非常感谢您的帮助,尤其是快速的回答。 这是我认为的最终解决方案:
#!/bin/bash
for file in $(find * -maxdepth 1 -iname "5*.par" ! -iname "*_*"); do
awk '/TASC/{x=}/START/{printf "TASC %s MJD %d %s",x,, FILENAME}' $file > mjd_vs_tasc
done
再次感谢你们。