我有一个包含 1000 个文件的文件夹;前面的所有字符均mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
指个人 ID(例如 NA21117、NA21119、NA21126、..)
NA21117.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
NA21119.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
NA21126.mapped.ILLUMINA.bwa.GIH.low_coverage.20121211.bam_dp
NA21127.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
NA21137.mapped.ILLUMINA.bwa.GIH.low_coverage.20120522.bam_dp
NA21142.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
NA21143.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
每个文件只有一行:
cat NA21143.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
1 115258827 10
对于每个文件,我想将单独的 ID 粘贴到文件的内容中并获得如下输出:
1 115258827 10 NA21143
有办法做吗?
答案1
普通的bash
for file in *.bam_dp; do
contents=$(< "$file")
echo "$contents ${file%%.*}" > "$file"
done
对于多行文件,仍然可以使用普通的 bash 来完成
for file in *.bam_dp; do
mapfile -t contents < "$file"
printf "%s\n" "${contents[@]/%/ ${file%%.*}}" > "$file"
done
笔记:
- 该
mapfile
命令将文件读取到行数组中。 - 参数
${var/pattern/string}
扩展对变量值进行搜索和替换。 (记录在案在手册中)- 如果模式以模式开头,则
%
模式锚定在字符串的末尾。在这里,我匹配字符串末尾的空模式。 - 该变量可以是数组扩展,在这种情况下,每个数组元素都会发生替换。
- 如果模式以模式开头,则
坦率地说,这种方法太聪明了,我会选择更明显的方法。
答案2
使用循环:
#!/bin/bash
shopt -s nullglob
for file in ???????.mapped.*bam_dp; do
[[ -f "$file" ]] || continue
id=${file%%.*} # grab the ID from file name
sed -i "s/$/ $id/" "$file" # modify the file in-place
done
答案3
从 $ARGV 中删除 .* 然后将 \t $ARGV 附加到文件中:
perl -i -pe '$ARGV=~s/\..*//; s/$/\t$ARGV/;' NA*
格伦的解决方案很可能运行得更快:
perl -i -lpe '$_ .= " " . substr($ARGV,0,index($ARGV,"."))' NA*
但如果每个文件只有一行,则大多数时间将在驱动器上查找。
答案4
awk
此方法与 GNU (Linux) 和 BSD (Mac) 版本的awk
.
awk '{ id=FILENAME ; sub(/\..*/,"",id) ; print $0 "\t" id }' *.bam_dp
id=FILENAME ; sub(/\..*/,"",id)
将每个文件名的第一部分*.bam_dp
(第一个之前的所有内容.
)存储为id
.print $0 "\t" id
打印每个文件的内容,然后打印制表符,然后打印记录的id
.
这将打印一个包含行的列表,如您的示例所示:
1 115258827 10 NA21143
原始文件不会被修改。例如,您可以通过添加到> file.txt
命令末尾来保存此输出。