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...
这似乎是一种一般问题,所以选择解决这个问题的语言并不重要。
为了好玩:一种bash方式:
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
我正在寻找一种将 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...
这似乎是一种一般问题,所以选择解决这个问题的语言并不重要。
为了好玩:一种bash方式:
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