Questão Concatene vários arquivos com base na similaridade do nome de arquivo: Bash do Windows (usando o Windows 10), Powershell ou linha de comando)


Atualmente estou preso no que parecia ser uma tarefa fácil. Eu tenho trabalhado em um script python que encontra certos arquivos na minha pasta Downloads e os despeja em outra subpasta dentro de uma pasta diferente. Em seguida, ele converte os PDFs dessa pasta designada em arquivos de texto, pois eu irei extrair informações dos arquivos (e é muito mais fácil trabalhar com o TXT).

Agora, estou preso nesta próxima parte: Tenho ~ 600 arquivos (e continuarei a ter mais) e quero combinar arquivos com base no nome do arquivo. É assim que os nomes dos arquivos são formatados ...

  • Txt_BI_ProfilesBI_Profile_Export_BB + Generic_August + 2016_GGP_20170316.pdf
  • Txt_BI_BrofilesBI_Profile_Export_BB + Generic_August + 2016_GGP_20170316.pdf (1)
  • Txt_BI_ProfilesBI_Profile_Export_Search_20170228.pdf
  • Txt_BI_ProfilesBI_Profile_Export_Search_20170228.pdf (1)

Observe como existem arquivos que compartilham o nome do arquivo, mas são distinguíveis com .pdf (1). Eu preciso de um script powershell ou bash que agrupa e mescla arquivos em arquivos de texto consolidados com base na similaridade do nome de arquivo.

Então, dado os nomes de arquivos acima, eu quero mesclar todo o conteúdo em

'TxtBI_ProfilesBI_Profile_Export_BB + Generic_August + 2016_GGP_20170316.pdf' + 'Txt_BI_ProfilesBI_Profile_Export_BB + Generic_August + 2016_GGP_20170316.pdf   (1) 'em um arquivo = 'BB + Generic_August + 2016_GGP'

e o mesmo vale para 'Search'. Para 'BB + Generic_August + 2016_GGP' e 'Pesquisa' grupo há até cerca de '.pdf (40)' arquivos diferentes, e há cerca de 10 ou mais grupos diferentes de arquivos que compartilham nomes de arquivos semelhantes. Eu escrevi um script python que tenta fazer isso Aqui mas tudo o que ele faz é dividir os nomes de arquivos [33:] e filenames.rsplit ('', 1) [0] (divide após o caractere 33 e o último '_') e não os combina em arquivos consolidados como mencionei acima. Posso fazer isso com powershell ou bash? Tal que divide os nomes dos arquivos (como acima mencionado) e, em seguida, combina-os se eles mantêm o mesmo nome de arquivo de texto?

Eu pensei que isso ia ser super fácil, mas não está funcionando para mim. Se alguém tiver algum insight / idéias / sugestões sobre como abordar isso, eu realmente aprecio isso! Já usei bash no passado antes para unix, mas já faz um tempo. Eu vou com o que for mais prático! Ainda um pouco novato quando se trata de programar ....


1


origem


Gotcha, eu vou manter isso em mente quando fizer perguntas aqui! Não sei bem qual é a diferença? Se isso ajudar, eu quero concatenar Group1_File + Group1_File (1) + Group1_File (2); Group2_File + Group2_ File (1) + Group2_File (2) em um arquivo "Group1_File", Group2_File, respectivamente. Eu acredito que fica difícil desde que todos os arquivos compartilham os mesmos primeiros 33 caracteres. - GGp
Não há problema, eu diria que a questão em si ainda está no tópico, pois tem mais a ver com a automação! A razão pela qual eu pergunto é que não tenho certeza se os PDFs podem ser simples / sensivelmente concatenados juntos; enquanto arquivos de texto podem. - bertieb
Desculpe se eu estava um pouco vago ... todos esses arquivos eram PDF, mas depois foram convertidos para TEXT (via script python) e descartados em uma pasta. - GGp
Você pode querer executar esta operação também em python, para ter um script consistente. - simlev
Eu adoraria, mas eu tenho um prazo chegando assim meio que preciso o mais cedo possível. @simlev Vou tentar a sua sugestão daqui a pouco, basta habilitar o bash no Windows 10 (não tenho ainda neste computador). - GGp


Respostas:


Editar: melhor solução que produz os nomes de arquivo de saída desejados

Fazendo uso de ls, awk e cat:

ls | awk '! /\([0-9]+\)/ {match($0, /Txt_BI_ProfilesBI_Profile_Export_([^.]+)/,matches); system("cat " $0 "* >"matches[1] ".txt")}'

Solicitado pela exibição de Matthew dos poderes de Powershell, eu teve para mostrar o mesmo pode ser alcançado em um ambiente bash. Esta é apenas uma das muitas maneiras, como é comum no mundo UNIX.

Explicação:

ls lista todos os elementos no diretório atual

awk linguagem de programação projetada para processamento de texto

! /\([0-9]+\)/ excluir nomes de arquivos que contenham um número entre parênteses

match($0, /Txt_BI_ProfilesBI_Profile_Export_([^.]+)/,matches)executar uma correspondência de expressão regular no nome do arquivo, capturando a parte entre o prefixo comum e o primeiro ponto

system(" executar um comando do sistema

cat " $0 "* concatenar arquivos que começam com o nome do arquivo

>"matches[1] ".txt" saída para um arquivo chamado como a expressão capturada e com uma extensão .txt


Primeira resposta: Você pode usar find, xargs, bash e cat:

find . -type f -regextype sed ! -regex "\./.*([0-9]\+)" | xargs -I{} bash -c 'cat {}* > {}.txt'

Isso é mais uma prova de conceito e pode ser refinada, já que os nomes dos arquivos de saída não são exatamente o que você procurava, mas devem ser suficientes para resolver o problema imediatamente.

Explicação:

find . pesquisar o diretório atual

-type f procure por arquivos

-regextype sed use o mecanismo de expressões regulares com sintaxe compatível com sed

! -regex "\./.*([0-9]\+)" exclui resultados que correspondem à expressão regular especificada, ou seja, aqueles que incluem um número entre parênteses no final

| xargs use cada resultado para construir um comando

-I{} no comando a seguir, substitua {} com cada find resultado

bash -c passar a seguinte string como um comando para bash

'cat {}* > {}.txt' concatenar os arquivos que começam com o nome do arquivo encontrado em um arquivo que tenha um nome composto find resultado e o .txt extensão


1



Após o seu post, eu tenho desenterrado bash (tem sido desde a última vez que usei) ... algumas perguntas embora. (1) para, match($0, /Txt_BI_ProfilesBI_Profile_Export_([^.]+)/,matches) na versão editada, posso usar substituto ([^.+]) com ([^.pdf+])? ... desde que alguns dos nomes de arquivos têm um "." na área entre o prefixo comum e .pdf... (2) Existe uma maneira de especificar o diretório do arquivo de saída concatenado? (3) Esta pode ser uma questão muito rudimentar, e peço desculpas se for ... antes de executar o script, eu tenho que cd para onde os arquivos estão localizados, correto? - GGp
Eu sinto fortemente que você deve ser capaz de fazer esses ajustes triviais. (1) eu usaria (.+).pdf. (2) especificar o diretório de saída após o >. (3) sim, ou use find inputdirectory -type f ao invés de ls. - simlev