Use um loop:
#!/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
Eu tenho uma pasta com 1000 arquivos; todos os caracteres antes de mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
referem-se ao ID do indivíduo (por exemplo, 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
Cada arquivo tem apenas uma linha:
cat NA21143.mapped.ILLUMINA.bwa.GIH.low_coverage.20130415.bam_dp
1 115258827 10
para cada um desses arquivos, quero colar o ID individual no conteúdo do arquivo e obter uma saída como:
1 115258827 10 NA21143
Existe alguma maneira de fazer isso?
plain bash
for file in *.bam_dp; do
contents=$(< "$file")
echo "$contents ${file%%.*}" > "$file"
done
para arquivos multi-line, ainda pode ser feito com o bash simples
for file in *.bam_dp; do
mapfile -t contents < "$file"
printf "%s\n" "${contents[@]/%/ ${file%%.*}}" > "$file"
done
notas:
mapfile
lê o arquivo em uma matriz de linhas. ${var/pattern/string}
faz uma pesquisa e substituição no valor da variável. (documentado no manual )
%
, o padrão será ancorado no final da string. Aqui, eu estou combinando o padrão vazio no final da string. Francamente, essa abordagem é inteligente demais, e eu gostaria de algo mais óbvio.
Remover. * de $ ARGV, em seguida, acrescente \ t $ ARGV ao arquivo:
perl -i -pe '$ARGV=~s/\..*//; s/$/\t$ARGV/;' NA*
A solução de Glenn provavelmente será mais rápida de executar:
perl -i -lpe '$_ .= " " . substr($ARGV,0,index($ARGV,"."))' NA*
embora se cada arquivo é apenas uma única linha, a maior parte do tempo estará procurando na unidade.
Este método é compatível com as versões GNU (Linux) e BSD (Mac) de awk
.
awk '{ id=FILENAME ; sub(/\..*/,"",id) ; print $0 "\t" id }' *.bam_dp
id=FILENAME ; sub(/\..*/,"",id)
*.bam_dp
filename (tudo antes do primeiro .
) como id
. print $0 "\t" id
id
. Isto irá imprimir uma lista com linhas como no seu exemplo:
1 115258827 10 NA21143
Os arquivos originais não serão modificados. Você pode salvar essa saída, por exemplo, adicionando > file.txt
ao final do comando.
Tags text-processing