[英]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 和 file2,它们的格式如下
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:我想要更新的 file1 如下:
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我知道如果 file1 中的字符串与我使用此命令提供的字符串匹配,我可以替换行
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?
我可以知道如何 go 关于这样做吗?
The actual files: File1:实际文件: 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:这是文件2:
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).我正在尝试用 file2 的底部块(从第 10 行第 1 行到第 17 行第 3 列)替换 file1 的 ATOMIC_POSITIONS 部分(从第 37 行第 2 列到第 44 行第 4 列)。
So the bottom of file1 should be something like this:所以 file1 的底部应该是这样的:
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: Since OP mentioned actual samples now, which are different from previous, so adding this now. 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
If happy with above's result then append > temp && mv temp Input_file1
to above.如果对上面的结果感到满意,那么 append
> temp && mv temp Input_file1
到上面。
EDIT: Since OP clarified question more got to know that row number from source(Input_file2) could be different from target(Input_file1), so let's say we have following Input_files.编辑:由于 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
Where variables source_row
is for Input_file from where we need to pickup the values and variable target_row
for target Input_file where we need to place the rows.其中变量
source_row
用于 Input_file,我们需要从中获取值,变量target_row
用于目标 Input_file,我们需要在其中放置行。
To save output into Input_file1 append at last of above command > temp && mv temp Input_file1
将 output 保存到 Input_file1 append 在上述命令的最后
> temp && mv temp Input_file1
In case you want to replace rows in Input_file1 by row number then try following.如果您想用行号替换 Input_file1 中的行,请尝试以下操作。
awk 'FNR==NR{a[FNR]=$1 OFS $2 OFS $3;next} {print $1,a[FNR]}' Input_file2 Input_file1
Output will be as follows. Output 如下。
XX b1 b2 b3
YY b4 b5 b6
Split file 1 into a header file and a footer file.将文件 1 拆分为 header 文件和页脚文件。
header file includes all the strings before row 37 (exclusive) and the footer includes rows after 45 (inclusive). header 文件包含第 37 行(不含)之前的所有字符串,页脚包含第 45 行(含)之后的行。 Then the code looks like the following:
然后代码如下所示:
cp file1.header file1
awk '\
NR == 10 || NR == 11 { print "Nb " $1 " " $2 " " $3 }\
NR >= 12 && NR <= 15 { print "I " $1 " " $2 " " $3 }\
NR == 16 || NR == 17 { print "O " $1 " " $2 " " $3 }\
' file2>> file1
cat ../file1.footer >> file1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.