cat/sed:日志文件片段的串联
cat/sed: concatenation of the fragments of the log filles
我有一个包含许多日志的文件夹。每个日志都有相似的格式。
这是log1
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_Y6A_nsp5holo_rep1.pdb
6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_06I_nsp5holo_rep1.pdb
4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
这是日志 3:
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_X7V_nsp5holo_rep1.pdb
2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
我需要将所有日志融合在一起,仅采用从 # H-bonds 开始的字符串,并在同一行中添加初始文件的名称:
这是结合log1 -log 3产生的融合日志:
log 1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log 2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
我尝试过使用 CAT 的简单解决方案,但它无法正常工作,因为在每个日志中我都有不同的行数,而 TAIL 无法正确识别它:
for log in ${results}/*_rep"${i}".log; do
log_name=$(basename "$log" .log)
echo "$log_name" >> ${results}/combined.log
cat $log | tail -n 10 >> ${results}/combined.log
done
我可以在某些特定的表达式中使用 cat 来识别行,或者我必须在 CAT 之前使用 SED 来从每个初始日志中删除未使用的行??
这个 awk 可以完成工作:
awk '
FNR==1 {p=0}
/^[0-9]+[[:space:]]+H-bonds$/ && FNR!=NR {printf "\n"}
/^[0-9]+[[:space:]]+H-bonds$/ {printf "log %d: ", ++c; p=1}
p==1'
对于每个给定的文件:
- 每个新文件开始时停止打印。
- 如果文件中的一行与
4 H-bonds
等的模式相匹配,如果它不是第一个文件,则打印一个空换行符。然后打印日志编号,并设置标志 p
以开始打印该日志文件。
- 请注意,您可以省略第一个,而不是对同一个正则表达式进行两次测试,并将
if (FNR!=NR) {printf "\n"}
放在第二个的块内。这主要是关于可读性。
- 我不确定文件名需要哪种模式表达式,
*.log
就是一个例子。也许 "${results}"/*_rep*.log
?
使用sed
$ for file in log{1..3}; do echo "${file##*/}: $(sed -n '/[0-9] H-bonds/,$p' "$file")"; echo ""; done
log1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
如果我没有误解这个问题,一个简单的 grep 似乎就是你所追求的:
grep -EH '^([0-9]+\s+)?H-bonds($| \()|^/' log*
或者如果您需要精确格式:
for log in log*; do
sed -n "s/^[0-9]\+\s\+H-bonds$/$log: &/; /^$log: /,${$s/$/\n/;p};" "$log"
done | sed '$d'
但我猜想额外的换行符是没有必要的,然后它就变得简单了:
for log in log*; do
sed -n "s/^[0-9]\+\s\+H-bonds$/$log: &/; /^$log: /,$p" "$log"
done
如果需要额外解释,我很乐意return编辑此回复。
$ awk 'FNR==1{f=0} /^[0-9]+ H-bonds/{[=10=]=sep FILENAME": " [=10=]; sep=ORS; f=1} f' log?
log1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
使用 SED 的“F”文件名选项
sed -i -n -s '1F;/[0-9] H-bonds/,$p' log* | sed -i -s '1N;s/\n/: /' log*
解释:
-i
---> 就地
-n
---> 禁用输出
-s
----> 将所有输入文件视为单独文件
1F
----> 打印第一行读取的输入文件名
/[0-9] H-bonds/,$p
---> 打印模式范围
N;s/\n: /
---> 合并前两行添加:
sed 的一个缺陷是“F”选项直接将文件名输出到 stdout 而不是模式 space 并且不能在一个 liner 中使用它
我有一个包含许多日志的文件夹。每个日志都有相似的格式。
这是log1
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_Y6A_nsp5holo_rep1.pdb
6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_06I_nsp5holo_rep1.pdb
4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
这是日志 3:
Finding intermodel H-bonds
Finding intramodel H-bonds
Constraints relaxed by 0.55 angstroms and 40 degrees
Models used:
1.1 SarsCov2_X7V_nsp5holo_rep1.pdb
2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
我需要将所有日志融合在一起,仅采用从 # H-bonds 开始的字符串,并在同一行中添加初始文件的名称:
这是结合log1 -log 3产生的融合日志:
log 1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log 2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
我尝试过使用 CAT 的简单解决方案,但它无法正常工作,因为在每个日志中我都有不同的行数,而 TAIL 无法正确识别它:
for log in ${results}/*_rep"${i}".log; do
log_name=$(basename "$log" .log)
echo "$log_name" >> ${results}/combined.log
cat $log | tail -n 10 >> ${results}/combined.log
done
我可以在某些特定的表达式中使用 cat 来识别行,或者我必须在 CAT 之前使用 SED 来从每个初始日志中删除未使用的行??
这个 awk 可以完成工作:
awk '
FNR==1 {p=0}
/^[0-9]+[[:space:]]+H-bonds$/ && FNR!=NR {printf "\n"}
/^[0-9]+[[:space:]]+H-bonds$/ {printf "log %d: ", ++c; p=1}
p==1'
对于每个给定的文件:
- 每个新文件开始时停止打印。
- 如果文件中的一行与
4 H-bonds
等的模式相匹配,如果它不是第一个文件,则打印一个空换行符。然后打印日志编号,并设置标志p
以开始打印该日志文件。 - 请注意,您可以省略第一个,而不是对同一个正则表达式进行两次测试,并将
if (FNR!=NR) {printf "\n"}
放在第二个的块内。这主要是关于可读性。 - 我不确定文件名需要哪种模式表达式,
*.log
就是一个例子。也许"${results}"/*_rep*.log
?
使用sed
$ for file in log{1..3}; do echo "${file##*/}: $(sed -n '/[0-9] H-bonds/,$p' "$file")"; echo ""; done
log1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
如果我没有误解这个问题,一个简单的 grep 似乎就是你所追求的:
grep -EH '^([0-9]+\s+)?H-bonds($| \()|^/' log*
或者如果您需要精确格式:
for log in log*; do
sed -n "s/^[0-9]\+\s\+H-bonds$/$log: &/; /^$log: /,${$s/$/\n/;p};" "$log"
done | sed '$d'
但我猜想额外的换行符是没有必要的,然后它就变得简单了:
for log in log*; do
sed -n "s/^[0-9]\+\s\+H-bonds$/$log: &/; /^$log: /,$p" "$log"
done
如果需要额外解释,我很乐意return编辑此回复。
$ awk 'FNR==1{f=0} /^[0-9]+ H-bonds/{[=10=]=sep FILENAME": " [=10=]; sep=ORS; f=1} f' log?
log1: 6 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? SER 144 OG /d UNL 1 S /? SER 144 HG 3.940 3.529
/? HIS 163 NE2 /d UNL 1 S no hydrogen 3.821 N/A
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.178 2.453
/d UNL 1 N /? THR 25 OG1 /d UNL 1 HN 2.755 2.270
/d UNL 1 N /? CYS 44 O /d UNL 1 HN 3.277 2.501
/d UNL 1 N /? ARG 188 O /d UNL 1 HN 3.056 2.055
log2: 4 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? THR 26 N /d UNL 1 O /? THR 26 H 3.579 2.754
/? ASN 142 ND2 /d UNL 1 O /? ASN 142 1HD2 3.250 2.324
/d UNL 1 N /? THR 26 O /d UNL 1 H 3.458 2.630
/d UNL 1 N /? HIS 163 NE2 /d UNL 1 HN 3.222 2.456
log3: 2 H-bonds
H-bonds (donor, acceptor, hydrogen, D..A dist, D-H..A dist):
/? GLN 189 NE2 /d UNL 1 O /? GLN 189 1HE2 3.185 2.258
/d UNL 1 N /? LEU 141 O /d UNL 1 HN 2.868 1.958
使用 SED 的“F”文件名选项
sed -i -n -s '1F;/[0-9] H-bonds/,$p' log* | sed -i -s '1N;s/\n/: /' log*
解释:
-i
---> 就地
-n
---> 禁用输出
-s
----> 将所有输入文件视为单独文件
1F
----> 打印第一行读取的输入文件名
/[0-9] H-bonds/,$p
---> 打印模式范围
N;s/\n: /
---> 合并前两行添加:
sed 的一个缺陷是“F”选项直接将文件名输出到 stdout 而不是模式 space 并且不能在一个 liner 中使用它