1

I'm currently stuck in what seemed to be an easy task. I've been working on a python script that finds certain files in my Downloads folder and dumps them into another sub-folder within a different folder. Then, it converts the PDFs in that designated folder into text files since I will be extracting info from the files(and it's just way easier to work with TXT).

Now, I'm stuck in this next part : I have ~ 600 files (and will continue to have more) and want to combine files based on filename. This is how the filenames are formatted...

  • 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)

Note how there are files that share filename but are distinguishable with .pdf(1) . I need a powershell or bash script that groups and merges files into a consolidated text files based on filename similarity.

So given the filenames above, I want to merge all the content in

'TxtBI_ProfilesBI_Profile_Export_BB+Generic_August+2016_GGP_20170316.pdf' + 'Txt_BI_ProfilesBI_Profile_Export_BB+Generic_August+2016_GGP_20170316.pdf (1)' into a file = 'BB+Generic_August+2016_GGP'

and same goes for 'Search'. For 'BB+Generic_August+2016_GGP' and 'Search' group there are up to about '.pdf(40)' different files, and there are about 10 or more different group of files that share similar filenames. I have written a python script that attempts to do this here but all it's doing is splitting the filenames[33:] and filenames.rsplit('',1)[0] (splits after the 33 character and the last '_') and not combining them into consolidated files as I mentioned above. Can I do this with powershell or bash? Such that it splits filenames(as abovementioned) and then combines them If they hold the same text filenname?

I thought this was going to be super easy but it's not working for me. If anyone has any insight/ideas/suggestions on how to approach this, I would truly appreciate it! Have used bash in the past before for unix, but it's been a while. I'll go with whatever is most practical! Still a bit of a novice when it comes to programming....

12
  • 1
    Gotcha, I'll def keep that in mind when asking questions on here! I'm not completely sure what the difference is? If this helps, I want to concatenate Group1_File + Group1_File (1) + Group1_File (2) ; Group2_File + Group2_ File (1) + Group2_File (2) into one file "Group1_File", Group2_File , respectively. I believe it gets difficult since ALL files share the same first 33 characters.
    – GGp
    Mar 29, 2017 at 15:56
  • 1
    No problem- I'd argue the question itself is still on-topic as it's more to do with automation! The reason I ask as is that I'm not sure PDFs can be simply / sensibly concatenated together; whereas text files can.
    – bertieb
    Mar 29, 2017 at 16:05
  • 1
    Sorry if I was a little too vague...all these files were once PDF but then were converted to TEXT ( via a python script) and dumped into a folder.
    – GGp
    Mar 29, 2017 at 16:12
  • 1
    You may want to perform this operation in python as well, in order to have one consistent script.
    – simlev
    Mar 29, 2017 at 16:16
  • 1
    I would love to, but I have a deadline coming up so kinda need it asap. @simlev I'll try your suggestion in a bit, just have to enable bash on Windows 10(don't have it on this computer yet).
    – GGp
    Mar 29, 2017 at 16:19

1 Answer 1

1

Edit: better solution that produces the desired output file names

Making use of ls, awk and cat:

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

Prompted by Matthew's display of Powershell's powers, I had to show the same can be achieved in a bash environment. This is just one of the many ways, as is common in the UNIX world.

Explanation:

ls lists all elements in the current directory

awk programming language designed for text processing

! /\([0-9]+\)/ exclude filenames that contain a number in parentheses

match($0, /Txt_BI_ProfilesBI_Profile_Export_([^.]+)/,matches) perform a regular expression match on the filename, capturing the part between the common prefix and the first dot

system(" execute a system command

cat " $0 "* concatenate files that start with the filename

>"matches[1] ".txt" output to a file named like the captured expression and having a .txt extension


First answer: You can use find, xargs, bash and cat:

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

This is more of a proof-of-concept and could be refined, as the output filenames are not exactly what you sought, but should be enough to solve your problem in the immediate.

Explanation:

find . search the current directory

-type f look for files

-regextype sed use the regular expression engine with sed-compatible syntax

! -regex "\./.*([0-9]\+)" exclude results that match the specified regular expression, i.e. those that include a number in parentheses at the end

| xargs use each result to construct a command

-I{} in the following command, substitute {} with each find result

bash -c pass the following string as a command to bash

'cat {}* > {}.txt' concatenate the files that start with the found filename into a file that has a name made up from the find result and the .txt extension

2
  • After your post, I have been digging up on bash(it's been AWHILE since I last used it)...few questions though. (1) For, match($0, /Txt_BI_ProfilesBI_Profile_Export_([^.]+)/,matches) in the edited version, can I use substitute ([^.+]) with ([^.pdf+])?...since some of the filenames have a " . " in the area between the common prefix and .pdf...(2) Is there a way to specify the concatenated output-file's directory? (3) This might be a VERY rudimentary question, and I apologize if it is...before executing the script, I have to cd to where the files are located, correct?
    – GGp
    Mar 30, 2017 at 13:37
  • I strongly feel you should be able to make these trivial adjustments yourself. (1) I'd use (.+).pdf. (2) specify the output directory after the >. (3) yes, or use find inputdirectory -type f instead of ls.
    – simlev
    Mar 30, 2017 at 14:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .