bash - How to replace a portion of file1 by a portion of file2 uing sed or awk, portion delineated by row and column no
问题描述
I have two files, say file1 and file2 and they are in the following format
file1:
many rows
36th rows
XX 1.1 1.2 9.9
YY 2.5 3.6 3.8
file2
several rows
9th row
5.5 6.6 9.8 T T T
5.4 5.6 7.8 T T T
What I want for the updated file1 is the following:
first row
XX 5.5 6.6 9.8
YY 5.4 5.6 7.8
I know I can replace lines if the string in file1 matches a string I provide by using this command
sed -i "s/1.1 1.2 9.9/5.5 6.6 9.8/" file1
However for this case, it should be much easier to replace the values using their row and column numbers. May I know how to go about doing this?
The actual files: File1:
&control
calculation='scf'
restart_mode='from_scratch'
prefix='prefix1'
pseudo_dir = '.'
nstep = 2000,
etot_conv_thr = 1.0E-6 ,
forc_conv_thr = 1.0D-4,
outdir = prefix1
/
&system
ibrav=0,
nat=8,
ntyp=3,
ecutwfc = 60.0,
ecutrho = 600,
/
&electrons
electron_maxstep = 250
mixing_beta = 0.1
conv_thr = 1.0d-10
/
CELL_PARAMETERS (angstrom)
3.9746359870249388 0.0000000000000000 0.0000000000000000
0.0000000000000000 7.5980663633997150 0.0000000000000000
0.0000000000000000 0.0000000000000000 24.1776735510378913
ATOMIC_SPECIES
I 126.90447d0 I.pbe-n-kjpaw_psl.1.0.0.UPF
Nb 92.906400d0 Nb.pbe-spn-kjpaw_psl.1.0.0.UPF
O 15.999400d0 O.pbe-n-kjpaw_psl.1.0.0.UPF
ATOMIC_POSITIONS {crystal}
Nb 0.7500000000000000 0.3084626380344986 0.5000000000000000
Nb 0.7500000000000000 0.8915373619655043 0.5000000000000000
I 0.7500000000000000 0.6000000000000014 0.5781487300676179
I 0.7500000000000000 0.1000000000000014 0.5953056146454921
I 0.7500000000000000 0.1000000000000014 0.4046943853545079
I 0.7500000000000000 0.6000000000000014 0.4218512699323820
O 0.2500000000000000 0.3124817357885405 0.5000000000000000
O 0.2500000000000000 0.8875182642114551 0.5000000000000000
K_POINTS {automatic}
12 6 1 0 0 0
This is file2:
Nb I O
1.00000000000000
3.9746359870249388 0.0000000000000000 0.0000000000000000
0.0000000000000000 7.5980663633997150 0.0000000000000000
0.0000000000000000 0.0000000000000000 24.1776735510378913
Nb I O
2 4 2
Selective dynamics
Direct
0.11 0.21 0.31 F F F
0.12 0.22 0.32 F F F
0.13 0.23 0.33 T T T
0.14 0.24 0.34 T T T
0.15 0.25 0.35 T T T
0.16 0.26 0.36 T T T
0.17 0.27 0.37 F T T
0.18 0.28 0.38 F T T
I'm trying to replace the ATOMIC_POSITIONS portion of file1 (from row 37 column 2 to row 44 column4) with the bottom chunk of file2 (from row 10 column 1 to row 17 column 3) .
So the bottom of file1 should be something like this:
ATOMIC_POSITIONS {crystal}
Nb 0.11 0.21 0.31
Nb 0.12 0.22 0.32
I 0.13 0.23 0.33
I 0.14 0.24 0.34
I 0.15 0.25 0.35
I 0.16 0.26 0.36
O 0.17 0.27 0.37
O 0.18 0.28 0.38
K_POINTS {automatic}
12 6 1 0 0 0
解决方案
EDIT2:由于OP现在提到了与以前不同的实际样本,所以现在添加。
awk '
FNR==NR{
if(!NF){
flag=""
}
if($0=="Direct"){
flag=1
}
if(flag){
array[++count]=$1 OFS $2 OFS $3
}
next
}
/ATOMIC_POSITIONS {crystal}/{
found=1
}
!NF{
found=count1=""
}
found{
print $1"\t"array[++count1]
next
}
1
' Input_file2 Input_file1
如果对上面的结果感到满意,请附加> temp && mv temp Input_file1
到上面。
编辑:由于 OP 澄清了问题,因此更多地知道来自源(Input_file2)的行号可能与目标(Input_file1)不同,所以假设我们有以下 Input_files。
awk -v source_row="10,11,12,13,14,15,16,17" -v target_row="37,38,39,40,41,42,43,44" '
BEGIN{
split(source_row,array_source,",")
num=split(target_row,array_target,",")
for(i=1;i<=num;i++){
replace_array[array_target[i]]
}
}
FNR==NR{
a[FNR]=$1 OFS $2 OFS $3
next
}
(FNR in replace_array){
print $1"\t"a[array_source[++count]]
next
}
1
' Input_file2 Input_file1
其中 variablessource_row
用于 Input_file,我们需要从中获取值和变量target_row
用于目标 Input_file 我们需要放置行的位置。
要将输出保存到 Input_file1,请在上述命令的最后附加> temp && mv temp Input_file1
如果您想用行号替换 Input_file1 中的行,请尝试以下操作。
awk 'FNR==NR{a[FNR]=$1 OFS $2 OFS $3;next} {print $1,a[FNR]}' Input_file2 Input_file1
输出如下。
XX b1 b2 b3
YY b4 b5 b6
推荐阅读
- c - 使用 bigarray 的 Ocaml/C 互操作:'未定义符号:caml_ba_alloc'
- node.js - Sequelize Select 父/子表中引用的模型
- javascript - 图标的条件渲染
- python - 使用类编码进行预测?
- android - 带有 WorkManager 的 Dagger 2 没有 Dagger-Android
- javascript - 将图像与文本右侧对齐
- shell - 如何使用 FFmpeg 并排播放两个视频?
- regex - 修改文件中的模式匹配行以及下一行
- python - Django模板渲染没有给出预期的结果
- python - Django 测试,验证是否自动创建了 Profile