Bash:将 4 个文件中的 4 行合并为一个文件

Bash: Merging 4 lines in 4 files into one single file

我正在寻找一种将 4 行 dna 探测结果合并为一行的方法。

这里的问题是:

我不想追加这些行。但是把它们联系起来

4条DNA检测线:

A----A----------A----A-A--AAAA-

-CC----CCCC-C-----CCC-C-------C

------G----G--G--G------G------

---TT--------T-T---------T-----

我需要这些是 1 行,不仅是附加的,而且没有破折号的混合。

结果的前几个字符:

 ACCTTAGCCCCGC...

这似乎是一种一般问题,所以选择解决这个问题的语言并不重要。

为了好玩:一种方式:

lines=(
    A----A----------A----A-A--AAAA-
    -CC----CCCC-C-----CCC-C-------C
    ------G----G--G--G------G------
    ---TT--------T-T---------T-----
)

result=""
for ((i=0;i<${#lines};i++)) ;do
    chr=- c=()
    for ((l=0;l<${#lines[@]};l++)) ;do
        [ "${lines[l]:i:1}" != "-" ] &&
            chr="${lines[l]:i:1}" &&
            c+=($l)
      done
    [ ${#c[@]} -eq 0 ] && printf 'Char #%d not replaced.\n' $i
    [ ${#c[@]} -gt 1 ] && c="${c[*]}" && chr="*" &&
         printf "Conflict at char #%d (lines: %s).\n" $i "${c// /, }"
    result+=$chr
  done
echo $result

使用提供的输入,没有冲突,所有字符都被替换。所以输出是:

ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC

注意:问题代表4个不同的文件,所以lines=语法可以是:

lines=($(cat file1 file2 file3 file4))

但是输入错误:

lines=(
    A----A---A-----A-----A-A--AAAA-
    -CC----CCCC-C-----CCC-C-------C
    ------G----G---G-G------G------
    ---TT--------T-T---------T-----
)

输出可能是:

Conflict at char #9 (lines: 0, 1).
Char #14 not replaced.
Conflict at char #15 (lines: 0, 2, 3).
Char #16 not replaced.

echo $result
ACCTTAGCC*CGCT-*-GCCCACAGTAAAAC

小型 perl 过滤器

但是如果不验证输入,这个小的 perl 过滤器可以完成这项工作: (感谢@jm666 提供 }{ 语法)

perl -nlE 'y+-+[=16=]+;$,|=$_}{say$,' <(cat file1 file2 file3 file4)

哪里

-n          process all lines without output
-l          whipe leading cariage return at end of lines
y+lhs+rhs+  replace (translate) chars from 'lhs' to 'rhs'
[=17=]          is the *null* character, binary 0.
$,          is a variable
|=          binary or, between himself and current line ($_)
}{          at END, once all lines processed

替代方法 - 不是很有效 - 但很短:

file="./gene"
line1=$(head -1 "$file")
seq ${#line1} | xargs -n1 -I% cut -c% "$file" | paste -s - | tr -cd '[A-Z\n]'

打印:

ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC

假设:每行的长度相同。

分解:

  • line1=$(head -1 "$file")将第一行读入变量line1
  • seq ${#line1} 生成一个数字序列1..char_count_in_the_line1,比如
1
2
..
31
  • xargs -n1 -I% cut -c% "$file" 将为上面的每个数字 运行 命令 cut 就像 cut -c22 filename - 从文件中提取给定的 column ,例如你会得到如下输出:
A
-
-
-

-
C
-
-

# and so on
  • paste -s - 会将以上几行与 \t (制表符)分隔符连接成一长行,例如:
A   -   -   -   -   C   -   -   -   C   -   -   -   -   -   T ... etc...
  • 最后 tr -cd '[A-Z\n]' 删除所有不是大写字符或换行符的东西,所以将得到最终的
ACCTTAGCCCCGCTGTAGCCCACAGTAAAAC