HLA中第二版的错误

1。在P169~P170页中的字符串比较的返回值是在 @c 中而不是在EAX中。(不过,这点在官方的帮助文档里已经有说明了)

procedure str.eq( src1:string; src2:string ); @returns( "@c" );


<think> 我们已知OptiType输出的每个样本的结果文件通常是一个tsv文件,其中包含HLA-I类基因(A, B, C)的分型结果(4位)。每个样本的结果文件可能位于不同的目录下,通常每个样本一个文件夹,或者每个样本一个结果文件。 假设每个样本的结果文件名为:`{样本名}_result.tsv` 或者类似,并且文件格式如引用[2]和[3]所示,包含表头(例如:A1, A2, B1, B2, C1, C2, Reads, Objective)以及相应的值。 目标:编写一个Linux命令(可以是shell脚本)来遍历所有样本的结果文件,将它们合并成一个大的表格,其中每一行对应一个样本,列包括样本ID以及各个HLA等位基因(A1, A2, B1, B2, C1, C2)和其他的信息(如Reads, Objective)。 步骤: 1. 我们需要收集所有样本的结果文件。假设所有样本的结果文件都在一个目录(比如`./optitype_results`)下,每个样本的结果文件在一个以样本名命名的子目录中,并且结果文件名为`{样本名}_result.tsv`,或者我们可以通过模式匹配找到这些文件(例如:`*/{样本名}_result.tsv`)。 2. 每个结果文件的第一行是标题行(列名),从第二行开始是数据。由于每个样本只有一个分型结果,所以每个文件只有一行数据(除了标题行)。 3. 合并表格时,我们希望第一列是样本ID(可以从文件名或目录名提取),然后后面是各个列(A1, A2, B1, B2, C1, C2, Reads, Objective)。注意,不同样本的结果文件列名相同,所以我们只需要取一次列名,但要加上一列“Sample”。 4. 我们可以使用awk或者循环来处理。这里我们使用一个简单的shell脚本,利用awk来实现。 假设结果文件的路径模式为:`./optitype_results/*/*_result.tsv` 或者 `./optitype_results/*_result.tsv`。为了灵活性,我们假设文件都在一个目录下,且文件名包含样本名。 具体思路: - 创建一个输出文件(合并后的表格),例如`combined_hla_results.txt`。 - 首先写入标题行:在原有标题行前面加上“Sample\t”。 - 然后遍历每一个结果文件,提取样本名(可以从文件名提取,例如去除路径和`_result.tsv`后缀),然后读取文件的数据行(第二行),并在前面加上样本名,然后写入输出文件。 但是要注意:不同样本的结果文件可能列数不一致?根据引用[2]和[3],似乎列名是一致的。 实现代码: 方式一:使用awk的BEGIN和FNR来处理多个文件 但是因为每个文件只有一行数据(除了标题),我们可以这样: 步骤: 1. 先打印标题行:Sample + 原标题行 2. 对于每个文件,读取第二行(如果有的话),然后打印样本名(从文件名提取)和该行的内容。 我们可以用循环遍历文件,并用awk处理每个文件。 方式二:用一个awk脚本一次性处理所有文件,但提取样本名稍微复杂。 这里我们采用shell循环,因为样本名需要从文件名中提取。 假设所有结果文件都在当前目录下的`optitype_results`目录中,且文件名为:`样本名_result.tsv`,并且每个文件都在样本名的子目录里?或者不在?根据引用[3]的结果文件位置,可能是每个样本一个文件夹,结果文件在文件夹内,文件名可能是固定的(比如`result.tsv`)?或者包含样本名?这里我们假设文件路径为:`optitype_results/Sample1/Sample1_result.tsv`。 为了通用,我们假设我们得到的文件列表是:`.../SampleX_result.tsv`,并且我们可以从文件名中提取SampleX。 具体步骤如下: 1. 定义结果文件存放的根目录:`DIR="./optitype_results"` 2. 找到所有的结果文件:`find "$DIR" -name "*_result.tsv"` 3. 输出文件:`combined_hla_results.txt` 脚本如下: ```bash #!/bin/bash # 定义输入文件目录和输出文件 DIR="./optitype_results" OUTPUT="combined_hla_results.txt" # 找到所有结果文件,并排序(可选) FILES=$(find "$DIR" -type f -name "*_result.tsv" | sort) # 首先处理第一个文件,获取标题行,并在前面加上"Sample\t" header=$(head -n1 $(echo "$FILES" | head -n1)) echo -e "Sample\t$header" > "$OUTPUT" # 循环处理每个文件 for file in $FILES; do # 从文件路径中提取样本名:假设文件名是 样本名_result.tsv # 例如:./optitype_results/Sample1/Sample1_result.tsv -> 我们取最后一个/后的文件名,然后去掉'_result.tsv' filename=$(basename "$file") sample="${filename%_result.tsv}" # 获取该文件的数据行(第二行) line=$(sed -n '2p' "$file") # 如果该文件有数据行,则写入输出文件 if [ -n "$line" ]; then echo -e "$sample\t$line" >> "$OUTPUT" else echo "警告: 文件 $file 没有数据行,跳过。" >&2 fi done echo "合并完成,结果保存在 $OUTPUT" ``` 但是,如果文件不是以`样本名_result.tsv`命名,而是每个样本目录下的固定文件名(比如`result.tsv`),那么我们就需要从目录名中提取样本名。例如,文件路径为:`./optitype_results/Sample1/result.tsv`,那么样本名应该是目录名(Sample1)。 修改提取样本名的部分: 如果文件路径是:`/path/to/SampleX/result.tsv`,那么我们可以这样提取样本名: ```bash # 从文件路径中提取样本名:取文件所在目录的目录名 dir_name=$(dirname "$file") sample=$(basename "$dir_name") ``` 或者,如果我们知道文件路径中包含样本名目录,且样本名目录就是结果文件所在的直接父目录,那么可以用上面的方法。 因此,我们需要根据实际文件存储结构来选择提取样本名的方式。 这里,我们假设两种情况都有可能,但用户需要根据实际情况调整。为了灵活性,我们可以让用户自行选择如何提取样本名,或者根据文件命名规律调整。 但是,根据引用[3]中的描述:“然后是一个tsv文件,分型结果”,并没有明确文件命名规则。因此,我们提供两种方式,并让用户根据实际情况修改。 我们修改脚本,提供两种提取样本名的方式,并通过注释让用户选择: 方式A:从文件名提取(如:`Sample1_result.tsv` -> 样本名为Sample1) 方式B:从所在目录名提取(如:`/optitype_results/Sample1/result.tsv` -> 样本名为Sample1) 我们可以在脚本中定义一个变量`NAME_SOURCE`,让用户设置是"filename"还是"dirname"。 改进后的脚本: ```bash #!/bin/bash # 定义输入文件目录和输出文件 DIR="./optitype_results" OUTPUT="combined_hla_results.txt" # 设置样本名来源:filename 表示从文件名提取,dirname 表示从所在目录名提取 NAME_SOURCE="filename" # 或修改为 "dirname" # 找到所有结果文件,并排序 FILES=$(find "$DIR" -type f -name "*.tsv" | sort) # 也可以根据实际情况调整文件名匹配模式 # 首先处理第一个文件,获取标题行,并在前面加上"Sample\t" first_file=$(echo "$FILES" | head -n1) header=$(head -n1 "$first_file") echo -e "Sample\t$header" > "$OUTPUT" # 循环处理每个文件 for file in $FILES; do # 根据设置的来源提取样本名 if [ "$NAME_SOURCE" = "filename" ]; then filename=$(basename "$file") sample="${filename%.tsv}" # 去掉.tsv后缀,注意:如果后缀是_result.tsv,我们可能想去掉_result和.tsv?这里我们保留全部,用户可以根据情况调整 # 如果文件名有固定后缀如_result,可以进一步处理 # sample="${sample%_result}" # 可选:去掉_result elif [ "$NAME_SOURCE" = "dirname" ]; then dir_name=$(dirname "$file") sample=$(basename "$dir_name") else echo "错误: 未知的样本名来源设置: $NAME_SOURCE" >&2 exit 1 fi # 获取该文件的数据行(第二行) line=$(sed -n '2p' "$file") # 如果该文件有数据行,则写入输出文件 if [ -n "$line" ]; then echo -e "$sample\t$line" >> "$OUTPUT" else echo "警告: 文件 $file 没有数据行,跳过。" >&2 fi done echo "合并完成,结果保存在 $OUTPUT" ``` 注意:这个脚本假设每个结果文件的第一行是标题,第二行是数据(且只有一行数据)。如果有的文件有多行数据(不应该出现,因为OptiType每个样本只输出一个分型结果),那么需要额外处理。 另外,如果结果文件的扩展名不一定是.tsv,也可能是.txt或其他,请修改find命令中的`-name`参数。 如果用户的结果文件命名不一致,请根据实际情况调整。 最后,将上述脚本保存为`combine_optitype.sh`,然后运行: ```bash bash combine_optitype.sh ``` 这样就会生成合并后的文件`combined_hla_results.txt`。 注意:如果结果文件没有标题行?根据引用[2]和[3],引用[2]中显示有标题行(#Locus Allele 1 Confidence Allele 2 Confidence),引用[3]中显示有标题行(A1 A2 B1 B2 C1 C2 Reads Objective)。但注意引用[2]的文件有注释行(以#开头),而引用[3]没有#号。所以需要确认实际结果文件格式。 如果结果文件的第一行以#开头,那么我们需要跳过?或者保留?在合并时,我们希望标题行没有#号,这样看起来统一。 因此,我们可以在读取标题行时去掉开头的#(如果有的话)。修改: 在读取第一个文件的标题行时,我们可以使用`sed`去掉行首的#和空格: ```bash header=$(head -n1 "$first_file" | sed -e 's/^#//' -e 's/^[[:blank:]]*//') ``` 这样,如果第一行是“# Locus Allele1 ...”,就会变成“Locus Allele1 ...”。 另外,注意引用[2]中的文件内容有多列(包括Confidence),而引用[3]中只有等位基因和Reads, Objective。所以不同本输出可能不同?用户需要确保所有结果文件格式相同。 因此,我们假设用户的所有结果文件格式一致。如果不一致,可能需要额外处理。 改进后的读取标题行和数据的代码: 针对每个文件,如果第一行以#开头,则去掉#。对于数据行,如果也有#开头,同样处理?但通常数据行没有#。所以只处理标题行。 因此,修改标题行的获取: ```bash header=$(head -n1 "$first_file") # 去掉行首的#和空格 header=$(echo "$header" | sed -e 's/^#//' -e 's/^[[:blank:]]*//') ``` 这样合并后的标题行就没有#了。 同样,在读取每个文件的数据行时,如果数据行也有#,也可以同样处理,但通常不会有。如果有,我们可以同样处理: ```bash line=$(sed -n '2p' "$file") line=$(echo "$line" | sed -e 's/^#//' -e 's/^[[:blank:]]*//') ``` 但为了保险,如果数据行没有#,就不用处理。所以这一步可选。 考虑到引用[2]中的文件内容如下: #Locus Allele 1 Confidence Allele 2 Confidence A A*02:65 0.008687167 A*02:65 NA 所以数据行没有#,因此我们只处理标题行。 最终脚本: ```bash #!/bin/bash # 定义输入文件目录和输出文件 DIR="./optitype_results" OUTPUT="combined_hla_results.txt" # 设置样本名来源:filename 表示从文件名提取,dirname 表示从所在目录名提取 NAME_SOURCE="filename" # 或修改为 "dirname" # 找到所有结果文件,并排序 FILES=$(find "$DIR" -type f -name "*.tsv" | sort) # 也可以根据实际情况调整文件名匹配模式 # 检查是否找到文件 if [ -z "$FILES" ]; then echo "错误: 没有找到任何结果文件!" >&2 exit 1 fi # 获取第一个文件并读取标题行 first_file=$(echo "$FILES" | head -n1) header=$(head -n1 "$first_file") # 去掉标题行行首的#和空格 header=$(echo "$header" | sed -e 's/^#//' -e 's/^[[:blank:]]*//') # 写入输出文件的标题行(加上Sample列) echo -e "Sample\t$header" > "$OUTPUT" # 循环处理每个文件 for file in $FILES; do # 根据设置的来源提取样本名 if [ "$NAME_SOURCE" = "filename" ]; then filename=$(basename "$file") sample="${filename%.tsv}" # 去掉.tsv后缀 # 如果文件名有固定后缀如_result,可以进一步处理 # sample="${sample%_result}" # 去掉_result,可选 elif [ "$NAME_SOURCE" = "dirname" ]; then dir_name=$(dirname "$file") sample=$(basename "$dir_name") else echo "错误: 未知的样本名来源设置: $NAME_SOURCE" >&2 exit 1 fi # 获取该文件的数据行(第二行) line=$(sed -n '2p' "$file") # 如果数据行以#开头,去掉#和空格(根据引用[2]的数据行没有#,所以可选) line=$(echo "$line" | sed -e 's/^#//' -e 's/^[[:blank:]]*//') # 如果该文件有数据行,则写入输出文件 if [ -n "$line" ]; then echo -e "$sample\t$line" >> "$OUTPUT" else echo "警告: 文件 $file 没有数据行,跳过。" >&2 fi done echo "合并完成,结果保存在 $OUTPUT" ``` 用户需要根据实际文件存放结构和命名方式调整`DIR`和`NAME_SOURCE`变量的值。 如果结果文件不是每个文件只有一行数据,而是有多行(例如,一个样本可能有多个候选分型结果?),那么需要进一步调整。但根据OptiType的文献,它输出的是最优的分型结果,所以应该只有一行数据。 如果文件格式不一致,比如有的文件有标题行,有的没有?这种情况应该避免,因为都是OptiType输出的。 最后,生成的`combined_hla_results.txt`是一个制表符分隔的文件,可以用Excel打开。 注意:如果结果文件中包含单引号(如引用[2]中B*39:05'),这不会影响文本格式。 请用户根据实际情况测试和调整脚本。 </think> 以下是一个将多个样本的OptiType HLA分型结果整合为单个表格的Linux脚本解决方案,参考了您提供的文件格式[^2][^3]: ```bash #!/bin/bash # 合并OptiType HLA分型结果脚本 # 输入:包含多个样本结果目录的父目录(默认当前目录) # 输出:combined_hla_results.txt 文本文件 # 设置结果文件搜索路径(可修改) RESULTS_DIR="./optitype_results" # 1. 创建输出文件并写入表头 echo -e "Sample\tA1\tA2\tB1\tB2\tC1\tC2" > combined_hla_results.txt # 2. 遍历所有样本分型文件 find "$RESULTS_DIR" -name "*HLAgenotype4digits" -print0 | while IFS= read -r -d $'\0' file; do # 从路径提取样本名(根据实际目录结构调整) sample_name=$(basename $(dirname "$file")) # 3. 提取HLA-I型基因分型结果(A/B/C) awk ' BEGIN {OFS="\t"; a1=a2=b1=b2=c1=c2="NA"} $1=="A" {a1=$2; a2=$4} $1=="B" {b1=$2; b2=$4} $1=="C" {c1=$2; c2=$4} END {print "'"$sample_name"'", a1, a2, b1, b2, c1, c2} ' "$file" done >> combined_hla_results.txt # 4. 添加处理完成信息 echo "合并完成!共处理 $(grep -c -v "Sample" combined_hla_results.txt) 个样本" ``` ### 使用说明: 1. **文件结构要求**: - 每个样本有独立目录(如 `sample1/`, `sample2/`) - 每个目录包含结果文件 `*HLAgenotype4digits`(如 `test-ClassI-class.HLAgenotype4digits`[^2]) 2. **执行方式**: ```bash bash merge_optitype.sh ``` 3. **输出示例**: ``` Sample A1 A2 B1 B2 C1 C2 sample1 A*02:65 A*02:65 B*39:05' B*13:48 C*08:02' C*08:02 sample2 A*03:01 A*31:01 B*15:11 B*48:01 C*03:03 C*08:01 ``` ### 关键功能说明: 1. **自动提取样本名**:从父目录名获取样本ID 2. **HLA-I型基因处理**:专注处理Class I基因(A/B/C)[^2] 3. **容错处理**:缺失值自动标记为"NA" 4. **高效遍历**:使用`find -print0`处理含特殊字符的路径 > **注意**:如果您的文件结构不同,请调整`sample_name`提取逻辑。对于Class II基因分型,可扩展脚本添加DR/DQ等字段[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值