[英]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.