[英]bash (sed/awk?) find line in file and print stuff 3 lines above?
[英]Bash script to move specific line or lines in a file to other line with awk or sed?
我看到这里得到了回答: Moving matching lines in a text file using sed和这里: How to move specified line in file to other place with regexp match (bash script)?
但是我在为我的案例实施它时遇到了问题。
我有一个 .csv 文件,其中包含:
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
Results:
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,GraphTests,37,26,11,70.00%
Mean Pass Rate for All Tests,,52,41,11,78.85%
我需要移动:
Mean Pass Rate for All Tests,,52,41,11,78.85%
直到“结果”正下方。 所以它看起来像这样:
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
Results:
Mean Pass Rate for All Tests,,52,41,11,78.85%
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,GraphTests,37,26,11,70.00%
不保证行号。 “使用的文件”部分可能包含更多文件。 此外,根据正在运行的测试,可能还有其他“平均通过率”行。 例如:
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
CLIENT FILE - /path/to/other/file/client.txt
Results:
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,ClientVarTests,12,12,0,100.00%
,GraphTests,37,26,11,70.00%
Mean Pass Rate for Client Tests,,27,27,0,100.00%
Mean Pass Rate for All Tests,,64,53,11,82.81%
在我的脚本中,我尝试了 awk:
MEAN_PASS_ALL="Mean Pass Rate for All Tests"
awk '/${MEAN_PASS_ALL}/{t=$0;next}1;/RESULTS/{print t}' ${CSV_FILE}
然而,所做的只是打印出 .csv 文件内容并且没有移动该行:
$ ./parse_results.sh
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
Results:
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,GraphTests,37,26,11,70.00%
Mean Pass Rate for All Tests,,52,41,11,78.85%
我也试过 sed,但这给出了错误:
sed "/.*Mean/d;/.*RESULTS/i"$(sed -n '/.*Mean/p' ${CSV_FILE}) ${CSV_FILE}
$ ./parse_results.sh
sed: can't read Pass: No such file or directory
sed: can't read Rate: No such file or directory
sed: can't read for: No such file or directory
sed: can't read All: No such file or directory
sed: can't read Tests,,52,41,11,78.85%: No such file or directory
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
Results:
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,GraphTests,37,26,11,70.00%
看起来它删除了该行,但它没有将其打印到我想要的位置,也没有“保存”更改。
如果有不止一行包含“平均通过率”,我希望它们都移到“结果”正下方:
我在这里做错了什么? 如何移动文件中的行并将文件与更改一起保存?
谢谢!
您可以使用 2 pass:
awk 'FNR == NR {
if ($0 ~ /^Mean Pass Rate /)
mpr = mpr ORS $0
next
}
/^Results:/ {
$0 = $0 mpr
}
!/^Mean Pass Rate /' file file
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
CLIENT FILE - /path/to/other/file/client.txt
Results:
Mean Pass Rate for Client Tests,,27,27,0,100.00%
Mean Pass Rate for All Tests,,64,53,11,82.81%
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,ClientVarTests,12,12,0,100.00%
,GraphTests,37,26,11,70.00%
您能否尝试在 GNU awk
进行以下、编写和测试。 如果您想对 Input_file 执行就地编辑,则将> temp && mv temp Input_file
附加到以下解决方案。
awk '
FNR==NR{
if($0~/Mean Pass Rate/){
val=(val?val ORS:"")$0
}
next
}
/Results:/{
print $0 ORS val
val=""
next
}
/Mean Pass Rate/{
next
}
1
' Input_file Input_file
说明:为以上添加详细说明。
awk ' ##Starting awk program from here.
FNR==NR{ ##Checking condition FNR==NR which will be TRUE when 1st Input_file is being read.
if($0~/Mean Pass Rate/){ ##Checking condition if line has Mean Pass Rate then do following.
val=(val?val ORS:"")$0 ##Creating val variable which is keep on having current line in it.
}
next ##next will skip all further statements from here.
}
/Results:/{ ##Checking condition if line has Results: then do following.
print $0 ORS val ##Printing current line ORS and val here.
val="" ##Nullifying val here.
next ##next will skip all further statements from here.
}
/Mean Pass Rate/{ ##Checking condition if line has Mean Pass Rate then do following.
next ##next will skip all further statements from here.
}
1 ##1 will print current line here.
' Input_file Input_file ##Mentioning Input_file names here.
使用ed
编辑文件,而不是sed
。 这意味着与他们一起工作,做一些事情,比如将行移动到文件中的任意位置:
ed -s "$CSV_FILE" <<'EOF'
/^Results:$/ka
g/^Mean Pass Rate/m'a\
ka
w
EOF
该第一擦伤ķS中的结果:行,然后对每行开始与平均数的合格率,米oves该行到标记之后,并且改变标志点到最近移动线(否则他们会以相反的顺序结束),和则w仪式修改后的文件恢复到磁盘。
使用两条平均通过率行在您的示例文件上运行它会导致它被编辑为:
Unit Tests
Model: A
Tue Sep 8 22:52:24 MDT 2020
User: br
Files Used:
DATA FILE - /path/to/file/data.txt
TEST TARBALL - /path/to/tarball/my_test.tar.bz2
CLIENT FILE - /path/to/other/file/client.txt
Results:
Mean Pass Rate for Client Tests,,27,27,0,100.00%
Mean Pass Rate for All Tests,,64,53,11,82.81%
Module,Test Suite,Total Tests,Tests Passed,Tests Failed,Pass Rate
Individual Test Run,ClientTests,15,15,0,100.00%
,ClientVarTests,12,12,0,100.00%
,GraphTests,37,26,11,70.00%
tac myFile | awk '
/^Mean Pass Rate/ { move=(!move)?$0:move ORS $0;next }
/^Results:/ { $0=move ORS $0 }
1' - | tac
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.