Como combinar vários arquivos com nomes semelhantes em pastas diferentes usando o comando unix?

1

Eu sei que esta pergunta foi feita e respondida antes, tentei o código, mas não obtive uma saída correta.

Eu tenho 2 pastas: vanila1 e vanila2, cada uma tem 400 arquivos com nomes semelhantes

ls vanila1
MB.2613.007_0021.ED4_KS1A29-7_338_all
MB.2613.007_0022.ED9_SD2A27-1_180_all
MB.2613.007_14.ED14_IA2A35-2_310_all

ls vanila2
MB.2613.007_0021.ED4_KS1A29-7_338_all
MB.2613.007_0022.ED9_SD2A27-1_180_all
MB.2613.007_14.ED14_IA2A35-2_310_all

Eu quero combinar arquivos com nomes idênticos e estou usando isso:

ls vanila1 | while read FILE; do
  cat vanila1/"$FILE" vanila2/"$FILE" >> all_combined/"$FILE"
done

Eu não obtenho uma saída correta, o número de linhas no arquivo combinado é mais que a soma de arquivo1 e arquivo 2. Estou fazendo algo errado?

    
por Anna1364 14.02.2018 / 20:21

2 respostas

1

Tenho um palpite de que você pode ter executado o loop mais de uma vez e, como você usa o operador de redirecionamento >> , que acrescenta dados, seus arquivos de resultado crescem sempre.

Em vez disso (e aqui estou evitando usar ls também, veja a discussão em " Por que * não * analisar 'ls'? "por razões):

for name in vanila1/*; do
    base_name=${name##*/}

    if [ -f "vanila2/$base_name" ]; then
        cat "$name" "vanila2/$base_name" >"all_combined/$base_name"
    else
        printf 'No file in vanila2 corresponds to "%s"\n' "$name" >&2
    fi
done

A substituição de variável ${name##*/} transforma um nome de caminho como vanila1/MB.2613.007_0021.ED4_KS1A29-7_338_all em apenas MB.2613.007_0021.ED4_KS1A29-7_338_all , isto é, remove todas as coisas antes de / , incluindo a barra (esse é o componente de nome de arquivo do nome do caminho ou "o nome base "). Isso pode ser substituído por $(basename "$name") .

Se houver um arquivo em vanila2 correspondente ao nome selecionado em vanila1 , os dois serão concatenados e colocados no diretório all_combined . Caso contrário, há uma mensagem de diagnóstico sobre esse fato.

Usando > em vez de >> , qualquer arquivo existente em all_combined com o mesmo nome será substituído em vez de anexado a.

Se você tiver outros arquivos ou diretórios em vanila1 , poderá modificar o padrão vanila1/* no loop para algo que corresponda apenas aos arquivos em que está interessado, por exemplo exemplo vanila1/*_all ou similar.

    
por 14.02.2018 / 21:12
-1

Então você tem arquivos com nomes idênticos em dois diretórios, e onde ambos os arquivos estão presentes para concatená-los?

for file in dir1/*; do
   otherfile="$(basename "$file")"
   if [[ -r dir2/"${otherfile}" ]]; then
       cat "$file" dir2/"$otherfile" >> combined/"$otherfile"
   fi
done
    
por 14.02.2018 / 20:44