Hi,
I just wanted to share with you this script.
Use Case:
Exports all the outgoing links files insiode a single note to a new folder. This folder should be outside your vault. (Otherwise, you will create additional copies of the same files)
These linked files can be located anywhere in your vault.
How to use:
save the script to a “CopyFileLinksToFolder.py” file
Parameters are set in the main() function
Files extensions to be copied
possible_extensions = [‘.md’, ‘.png’, ‘.jpg’, ‘.jpeg’, ‘.pdf’, ‘.doc’,‘.docx’, ‘.xlsx’]
Relative Path of the Obsidian note. Use Obsidian Command “Copy file path”
file_path = r’@Mynote.md’
Path to your Obsidian vault
vault_path = r’C:@PARA’
Destination root folder to copy the files to. The filename will be used as subfolder
dest_root_folder = r’C:\TEMP’
import os
import shutil
import re
from pathlib import Path
def get_file_name_without_extension(file_path):
"""
Extracts the file name without the extension from a given file path.
:param file_path: The full path to the file.
:return: The file name without its extension.
"""
base_name = os.path.basename(file_path)
name_without_extension = os.path.splitext(base_name)[0]
return name_without_extension
def read_obsidian_note(note_path):
with open(note_path, 'r', encoding='utf-8') as file:
content = file.read()
return content
def extract_links(content):
# Regular expression to match Obsidian wiki links: [[Link to file]]
link_pattern = re.compile(r'\[\[([^\]]+)\]\]')
links = link_pattern.findall(content)
#print(f"Extracted links: {links}")
return links
def find_file_in_vault(link, vault_path, possible_extensions):
# Split link to handle cases with aliases or headings
link = link. Split('|')[0]
link = link.split('#')[0]
# Search for the file in the vault recursively
for root, dirs, files in os.walk(vault_path):
for file_name in files:
if file_name.startswith(link):
_, file_extension = os.path.splitext(file_name)
if file_extension.lower() in possible_extensions:
return Path(root) / file_name
return None
def copy_files(links, vault_path, dest_folder, possible_extensions):
os.makedirs(dest_folder, exist_ok=True)
for link in links:
src_file = find_file_in_vault(link, vault_path, possible_extensions)
if src_file:
if src_file.suffix.lower() in possible_extensions:
dest_file = Path(dest_folder) / src_file.name
shutil.copy(src_file, dest_file)
print(f'Copied [{src_file.name}] to [{dest_folder}]')
else:
print(f'File [{src_file.name}] is excluded from exporting due to its extension.')
else:
if any(link.endswith(ext) for ext in possible_extensions):
print(f'File for link [{link}] does not exist!')
else:
print(f'File for link [{link}] is excluded from exporting.')
def main():
# INPUTS #######################
# Files extensions to be copied
possible_extensions = ['.md', '.png', '.jpg', '.jpeg', '.pdf', '.doc','.docx', '.xlsx'] # Add other extensions as needed
# Relative Path of the Obsidian note. Use Obsidina Command "Copy file path"
file_path = r'@Mynote.md'
# Path to your Obsidian vault
vault_path = r'C:\@PARA'
# Destination root folder to copy the files to. The filename will be used as subfolder
dest_root_folder = r'C:\TEMP'
# EXPORTING FILES ######################
# Build the full note path
note_path = vault_path + '/' + file_path
# Build the destination folder path
file_name = get_file_name_without_extension(file_path)
dest_folder = dest_root_folder + '\\' + file_name
print('Exporting file...[' + file_name + ']')
# Read the note
content = read_obsidian_note(note_path)
# Extract links from the note
links = extract_links(content)
# Copy the linked files to the destination folder
copy_files(links, vault_path, dest_folder, possible_extensions)
if __name__ == '__main__':
main()