String 更改大文件列的字符

String 更改大文件列的字符,string,shell,sed,awk,String,Shell,Sed,Awk,我必须用另一个文件的对应列替换大文件中每一行(备用)的单个第n个字符。例如,我每五个字符就换一次 文件1: >chr1:101842566-101842576 CCTCAACTCA >chr1:101937281-101937291 GAATTGGATA >chr1:101964276-101964286 AAAAAATAGG >chr1:101972950-101972960 ggctctcatg >chr1:101999969-1019999

我必须用另一个文件的对应列替换大文件中每一行(备用)的单个第n个字符。例如,我每五个字符就换一次

文件1:

 >chr1:101842566-101842576
  CCTCAACTCA
 >chr1:101937281-101937291
 GAATTGGATA
 >chr1:101964276-101964286
 AAAAAATAGG
 >chr1:101972950-101972960
 ggctctcatg
 >chr1:101999969-101999979
 CATCATGACG
文件2:

 G
 A
 T
 A
 C
输出:

 >chr1:101842566-101842576
 CCTCGACTCA
 >chr1:101937281-101937291
 GAATAGGATA
 >chr1:101964276-101964286
 AAAATATAGG
 >chr1:101972950-101972960
 ggctAtcatg
 >chr1:101999969-101999979
 CATCCTGACG

每个(备用)行中的字符数可能很大。而且行数也很大。如何有效地实现这一点?

以下是使用awk的一种方法:

awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
说明:

  • 我们迭代第二个文件,并将其存储在一个按行号索引的数组中
  • 一旦将第二个文件加载到内存中,我们将移动到第二个文件
  • 我们查找不以
    开头的行
  • 找到后,我们替换数组中的值。我们通过使用
    substr
    函数来实现这一点
  • 定义的变量
    n
    允许您修改第n个字符
  • 对于没有
    的行,我们使用默认的
    1
    按原样打印它们 印刷
  • 此解决方案假定文件的格式如上所示。也就是说,第一个文件总是以
    开头,然后是要进行更改的行。第二个文件的替换将按照其显示的顺序进行
演示:

每五个字符:

$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
>chr1:101842566-101842576
CCTCGACTCA
>chr1:101937281-101937291
GAATAGGATA
>chr1:101964276-101964286
AAAATATAGG
>chr1:101972950-101972960
ggctAtcatg
>chr1:101999969-101999979
CATCCTGACG
$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=3 f2 f1
>chr1:101842566-101842576
CCGCAACTCA
>chr1:101937281-101937291
GAATTGGATA
>chr1:101964276-101964286
AATAAATAGG
>chr1:101972950-101972960
ggAtctcatg
>chr1:101999969-101999979
CACCATGACG
每三个字符:

$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
>chr1:101842566-101842576
CCTCGACTCA
>chr1:101937281-101937291
GAATAGGATA
>chr1:101964276-101964286
AAAATATAGG
>chr1:101972950-101972960
ggctAtcatg
>chr1:101999969-101999979
CATCCTGACG
$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=3 f2 f1
>chr1:101842566-101842576
CCGCAACTCA
>chr1:101937281-101937291
GAATTGGATA
>chr1:101964276-101964286
AATAAATAGG
>chr1:101972950-101972960
ggAtctcatg
>chr1:101999969-101999979
CACCATGACG

以下是使用awk的一种方法:

awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
说明:

  • 我们迭代第二个文件,并将其存储在一个按行号索引的数组中
  • 一旦将第二个文件加载到内存中,我们将移动到第二个文件
  • 我们查找不以
    开头的行
  • 找到后,我们替换数组中的值。我们通过使用
    substr
    函数来实现这一点
  • 定义的变量
    n
    允许您修改第n个字符
  • 对于没有
    的行,我们使用默认的
    1
    按原样打印它们 印刷
  • 此解决方案假定文件的格式如上所示。也就是说,第一个文件总是以
    开头,然后是要进行更改的行。第二个文件的替换将按照其显示的顺序进行
演示:

每五个字符:

$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
>chr1:101842566-101842576
CCTCGACTCA
>chr1:101937281-101937291
GAATAGGATA
>chr1:101964276-101964286
AAAATATAGG
>chr1:101972950-101972960
ggctAtcatg
>chr1:101999969-101999979
CATCCTGACG
$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=3 f2 f1
>chr1:101842566-101842576
CCGCAACTCA
>chr1:101937281-101937291
GAATTGGATA
>chr1:101964276-101964286
AATAAATAGG
>chr1:101972950-101972960
ggAtctcatg
>chr1:101999969-101999979
CACCATGACG
每三个字符:

$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=5 f2 f1
>chr1:101842566-101842576
CCTCGACTCA
>chr1:101937281-101937291
GAATAGGATA
>chr1:101964276-101964286
AAAATATAGG
>chr1:101972950-101972960
ggctAtcatg
>chr1:101999969-101999979
CATCCTGACG
$ awk 'NR==FNR{a[NR]=$1;next}!/^>/{$1=substr($1,1,n-1) a[++i] substr($1,n+1)}1' n=3 f2 f1
>chr1:101842566-101842576
CCGCAACTCA
>chr1:101937281-101937291
GAATTGGATA
>chr1:101964276-101964286
AATAAATAGG
>chr1:101972950-101972960
ggAtctcatg
>chr1:101999969-101999979
CACCATGACG

这就是我将如何使用perl。首先将所有文件2读取到一个数组中,然后迭代该数组,从文件1中读取两行和两行,未经修改地打印第一行,然后更改第二行的第5个字符:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
#use Data::Printer;

# Read all of file2

my $lines;

open(FILE, $ARGV[1]);
{
    local $/;
    $lines = <FILE>;
}
close(FILE);

my @new_chars = split(/\n/, $lines);

# Read and process file1

open(FILE, $ARGV[0]);

foreach my $new_char (@new_chars) {
    # >chr1:101842566-101842576
    my $line = <FILE>;
    print $line;
    #  CCTCAACTCA
    $line = <FILE>;
    $line =~ s/^(....)./$1$new_char/; # Replace 5th character
    print $line;
}

close(FILE);
#/usr/bin/perl
严格使用;
使用警告;
使用诊断;
#使用数据打印机;
#读取所有文件2
我的$line;
打开(文件$ARGV[1]);
{
本地$/;
$lines=;
}
关闭(文件);
my@new_chars=拆分(/\n/,$line);
#读取并处理文件1
打开(文件$ARGV[0]);
foreach我的$new\u char(@new\u chars){
#>chr1:101842566-101842576
我的$line=;
打印$行;
#CCTCAACTCA
$line=;
$line=~s/^(..)/$1$new_char/#替换第5个字符
打印$行;
}
关闭(文件);

这就是我将如何使用perl。首先将所有文件2读取到一个数组中,然后迭代该数组,从文件1中读取两行和两行,未经修改地打印第一行,然后更改第二行的第5个字符:

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
#use Data::Printer;

# Read all of file2

my $lines;

open(FILE, $ARGV[1]);
{
    local $/;
    $lines = <FILE>;
}
close(FILE);

my @new_chars = split(/\n/, $lines);

# Read and process file1

open(FILE, $ARGV[0]);

foreach my $new_char (@new_chars) {
    # >chr1:101842566-101842576
    my $line = <FILE>;
    print $line;
    #  CCTCAACTCA
    $line = <FILE>;
    $line =~ s/^(....)./$1$new_char/; # Replace 5th character
    print $line;
}

close(FILE);
#/usr/bin/perl
严格使用;
使用警告;
使用诊断;
#使用数据打印机;
#读取所有文件2
我的$line;
打开(文件$ARGV[1]);
{
本地$/;
$lines=;
}
关闭(文件);
my@new_chars=拆分(/\n/,$line);
#读取并处理文件1
打开(文件$ARGV[0]);
foreach我的$new\u char(@new\u chars){
#>chr1:101842566-101842576
我的$line=;
打印$行;
#CCTCAACTCA
$line=;
$line=~s/^(..)/$1$new_char/#替换第5个字符
打印$行;
}
关闭(文件);

您可以使用Python中的
mmap
替换文件中的列:

#/usr/bin/env蟒蛇3
“”“替换大文件中的一列。
用法:
$/替换就地文件1文件2 5
"""
导入系统
从mmap导入访问\u写入,mmap
def main():
ncolumn=int(sys.argv[3])-1#第1列是1
打开(sys.argv[1],'r+b')作为文件1:
使用mmap(file1.fileno(),0,access=access\u WRITE)作为mm:
打开(sys.argv[2],“rb”)作为文件2:
尽管如此:
mm.readline()#每隔一行忽略一行
pos=mm.tell()#记住当前位置
如果不是mm.readline():#EOF
打破
替换=文件2.readline().strip()[0]
mm[pos+N柱]=更换#更换柱
main()

它假设您正在用字节替换一个字节,即文件中没有移动任何内容。

您可以使用Python中的
mmap
替换文件中的列:

#/usr/bin/env蟒蛇3
“”“替换大文件中的一列。
用法:
$/替换就地文件1文件2 5
"""
导入系统
从mmap导入访问\u写入,mmap
def main():
ncolumn=int(sys.argv[3])-1#第1列是1
打开(sys.argv[1],'r+b')作为文件1:
使用mmap(file1.fileno(),0,access=access\u WRITE)作为mm:
打开(sys.argv[2],“rb”)作为文件2:
尽管如此:
mm.readline()#每隔一行忽略一行
pos=mm.tell()#记住当前位置
如果不是mm.readline():#EOF
打破
替换=文件2.readline().strip()[0]
mm[pos+N柱]=更换#更换柱
main()
它假定您正在用字节替换一个字节,即文件中没有移动任何内容。

这可能适用于您(GNU-sed、paste和cat):

将文件2中的数据嵌入文件1,然后重新排列。

这可能适合您(GNU-sed、paste和cat):

从文件中嵌入数据