我有许多目标行的日志文件,我希望'grep',例如:
EGPA019_90pc.recode.2.log:Cross-Entropy (masked data): 0.556984
我希望将“2”和“0.556984”用标签分隔成文件
所以,如果我输入:
grep "Cross-Entropy (masked data):" *.log | cut -d '.' -f 3 >> targetFile.txt
我得到“2”,并且:
grep "Cross-Entropy (masked data):" *.log | cut -d ' ' -f 4 >> targetFile.txt
我得到了“0.556984”。但是我怎么能在一行代码中写这个以获得“2”然后在我的目标文件中的同一行上的选项卡然后“0.556984”?
非常感谢
克里夫
答案 0 :(得分:2)
您可以使用grep
和一些bash
内置的regEx功能。
grep -h "Cross-Entropy (masked data):" *.log | while IFS= read -r string; do
[[ "$string" =~ .recode.([[:digit:]]+).*:\ (.*)$ ]]
printf "%s\t%s\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]//[[:blank:]]}";
done
我的输入文件
$ cat *.log
EGPA019_90pc.recode.2.log:Cross-Entropy (masked data): 0.556984
EGPA019_90pc.recode.9.log:Cross-Entropy (masked data): 0.996984
EGPA019_90pc.recode.7.log:Cross-Entropy (masked data): 0.756984
$ grep -h "Cross-Entropy (masked data):" *.log | while IFS= read -r string; do
[[ "$string" =~ .recode.([[:digit:]]+).*:\ (.*)$ ]]
printf "%s\t%s\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]//[[:blank:]]}"; done
2 0.556984
9 0.996984
7 0.756984
说明: -
bash
regEx功能来捕获所需的字符串,而不是使用其他本机工具。grep
的输出通过管道传输以应用regEx [ "$string" =~ recode.([[:digit:]]+).*:\ (.*)$ ]]
,它会捕获您所需的条目,数字和十进制数字。printf
打印这些变量。第二次捕获,即十进制数字在开头有空格字符,将其删除"${BASH_REMATCH[2]//[[:blank:]]}"
您也可以将它包装在shell脚本中,如下所示: -
#!/bin/bash
while IFS= read -r string; do
[[ "$string" =~ .recode.([[:digit:]]+).*:\ (.*)$ ]]
printf "%s\t%s\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]//[[:blank:]]}"
done < <(grep -h "Cross-Entropy (masked data):" *.log)
或者)grep
使用PCRE标记-P
选项,使用xargs
过滤输出。
grep -Pho '\.recode\.\K\d+|: \K.*' *.log | xargs -n2 -d'\n'
2 0.556984
9 0.996984
7 0.756984
(或)使用更简单的perl
regEx语法。
perl -lne 'print "$1 $2" if /\.recode\.(\d+).*:\s+(.*)/' *.log
2 0.556984
9 0.996984
7 0.756984
答案 1 :(得分:0)
我认为我是使用awk
执行此操作而不是解析grep
的输出。
我没有对您的数据集进行测试,但在我看来,以下情况应该有效。
awk '/^Cross-Entropy \(masked data\):/ {split(FILENAME,a,".");printf("%s\t%s\n", a[3], $NF}' *.log
它有点像单线。作为独立脚本,它可能如下所示:
#!/usr/bin/awk -f
/^Cross-Entropy \(masked data\):/ {
split(FILENAME,a,".")
printf("%s\t%s\n", a[3], $NF
}
将其保存在一个文件中,使其可执行,并为自己创建一个全新的shell命令。
请注意,这可以通过使用字段拆分来实现,而不是使用正则表达式。
答案 2 :(得分:0)
您可以使用sed
删除不需要的内容:
grep "Cross-Entropy (masked data):" *.log | sed 's/.*recode.//;s/\..*: //'
可以合并grep
和sed
:
sed -n '/Cross-Entropy (masked data):/ {s/.*recode.//;s/\..*: //;p}' *.log