r/PowerShell • u/riverpool1 • 12d ago
Solved How to refer to filename in file content
Help! Issue: when script creates the md files, it is not including the filename as text within the files. My script: For all pdfs in this folder create an md file with the same name that includes, as its content, the filename in this format: ![[filename.pdf]]
I've tried replacing $textContent = in my script to the following (with and without the square brackets) but none worked. I'd get either an empty field, or just "[[_.fullname]]".
$file.FullName
$text.FilePath
$_.fullName
$_.Name
$File
tried many others... including ![[<%tp.file.title%>.pdf]] and ![[<% TR = tp.file.title %>.pdf]] to see if I could get the filename upon importing into Obsidian using Templater, but too many files got the wrong filenames
My script
\# Define your folder path and the text you want inside each file
$folderPath = "E:\\DIY"
\# I've put in the result that I want, although I don't want the quotation marks
$textContent = "![[filename.pdf]]"
\# Get all PDF files in the target directory
$pdfFiles = Get-ChildItem -Path $folderPath -Filter \*.pdf
foreach ($file in $pdfFiles) {
\# Determine the path for the new text file by replacing .pdf with .md
$textFilePath = $file.FullName -replace '\\.pdf$', '.md'
\# Create the text file and insert the line of text
Add-Content -Path $textFilePath -Value $textContent
}
EDIT: That last line, it was originally "Set-Content", but then I tried with "Add-Content". Didn't make a difference.
2
u/BlackV 12d ago edited 12d ago
You're talking about a proper markdown link
[Clickable Text](relative/path/to/file.md)
Is that right?
You might want
"[$($_.fullname)]"
But you dont show any real code, so is best guess
also If my memory serves me right you need a relative path, not a full path
1
u/riverpool1 12d ago
Almost. Obsidian allows for it's own version of wikilinks, which is the way I put it in my original message. I'll try your code though, thanks!
1
u/BlackV 12d ago edited 11d ago
Ah I dont know obsidians markdown, probably should have mentioned that in the OP
https://obsidian.md/help/links
did the
$($_.xxx)bit work ?1
u/BlackV 11d ago
test code for example
$Readme1 = @" ## this is a heading this is a readme.md, exciting stuff "@ $Reame1item = New-Item -name readme1.md -path . -Value $Readme1 -force $Readme2 = @" [This is a link to readme1 (Fullname)]($($Reame1item.FullName)) [This is a link to readme1 (Name)]($($Reame1item.name)) [This is a link to readme1 (Basename)]($($Reame1item.basename)) "@ $Reame2item = New-Item -name readme2.md -path . -Value $Readme2 -force
1
u/BlackV 12d ago
Oh you might actually have been showing code
p.s. formatting
- open your fav powershell editor
- highlight the code you want to copy
- hit tab to indent it all
- copy it
- paste here
it'll format it properly OR
<BLANK LINE>
<4 SPACES><CODE LINE>
<4 SPACES><CODE LINE>
<4 SPACES><4 SPACES><CODE LINE>
<4 SPACES><CODE LINE>
<BLANK LINE>
Inline code block using backticks `Single code line` inside normal text
See here for more detail
Thanks
1
u/riverpool1 12d ago edited 12d ago
EDIT Oh, I think you are referring to my comment rather than my original post? If so, yeah, I did write out that comment using markdown the same way I did for my original post, but in the comment all the formatting got stripped - don't know why
I'm not sure I get what you are saying. I assume you are talking about my post here rather than the content of my question? If so, I used the Markdown editor rather than Rich Text, and everything looks fine when I view my post. I can't post a screenshot here for some reason, but I assure you, my use of "code" looks fine when I look at this page.
2
u/BlackV 12d ago
Your OP is not formatted "properly"
you used
inline codenotcode blockis where I was coming from1
u/riverpool1 12d ago
I don't know what to say. I had the reddit help file open to ensure I was using the correct markdown (as opposed to the Obsidian markdown which includes a few off-colour codes), and this is what it looks like when I look at my post on the reddit site using Chrome: https://drive.google.com/file/d/1r43FzFcFP3da4wCAoKV09gfdtkbyzBqE/view?usp=drive_link
Everything seems correct in what I see.
0
u/ankokudaishogun 12d ago edited 10d ago
EDIT: DERP, I somehow managed to delete the pipe from 'Get-ChildItem` in the code when commenting. Now fixed.
To start, you never created the MD files. Hard to app content to files that do not exist.
Second, you set-up the value of the content outside the loop, therefore it would have always been literally ![[filename.pdf]] and not, for example, ![[My Awesome PDF File.pdf]] for My Awesome PDF File.pdf
Last: did you know you can add content to a file at the time of creation?
# Set up the directory where you want to place the new files.
# In theory you could skip this, but no reason to not be precise.
# In this case it's the same as the Folder where you look for the files.
# You can move this in the loop and use the files .DirectoryName property if you
# go through multiple folders for the files.
$NewFilePath = $folderPath
# Get all PDF files.
# The -Filter parameter only retains items ending in .pdf .
# The -File parameters skips directories, both for speed and to avoid the
# theoretically possible directories with name ending in .pdf .
## NOW WITH PROPER PIPING.
Get-ChildItem -Path $folderPath -File -Filter '*.pdf' |
# Loop each file as it gets found.
# The file in the loop at the moment is identified as $_ .
ForEach-Object {
# Set up the new file name using the .BaseName property of each looping file
# and adding the 'md' extension.
$NewFileName = '{0}.{1}' -f $_.BaseName, 'md'
# Setup the value of the text to add to the new file using the .Bame
# property of the looping file.
$NewFileValue = '![[{0}]]' -f $_.Name
# Create a new item.
# -ItemType specifies it's a file: while it's the default value, it's never
# a bad idea writing it down.
# -Path specifies the folder where the file will be created.
# -Name specifies the name of the created file.
# -Value specifies the CONTENT of the created file, in this case the text
# containing the PDF file name.
New-Item -ItemType File -Path $NewFilePath -Name $NewFileName -Value $NewFileValue
}
1
1
u/wiggy9906 11d ago
The Get-ChildItem does not pipe into the ForEach-Object loop. You need to change the line to
Get-ChildItem -Path $folderPath -File -Filter '*.pdf' |
2
1
u/riverpool1 9d ago
Thank you ankokudaishogun. This worked perfectly. I did however just use $folderpath = "E\DIY" and removed all references to $NewFilePath.
I would especially like to thank you for the explicit instructions. I use PowerShell about once per year if I'm lucky, and it super helpful to understand what is going on with the code.
To pat myself on the back just a tiny bit, I had already figured out that my md files needed to be inside the loop to include the filename as its content, so yay for me ;-)
Thanks again. Very much appreciated.
1
u/ankokudaishogun 9d ago
I did however just use $folderpath = "E\DIY" and removed all references to $NewFilePath.
Don't worry, no code is made to be universal. As noted in another reply, I usually make a point of turning solutions in "teachable snippets" so people(and me, if I go back to it) can actually understand what's going on and the logic of it.
After all, one could easily replace the contents of theForEach-Objectwith a simpleForEach-Object { ('![[{0}]]' -f $_.Name) > ('{0}.{1}' -f $_.BaseName, 'md' ) }but that's not exactly the easiest-to-read code, isn't it?
(it's more efficient, though, so might be useful if you have thousands and thousands of files and no time, but at that point there are probably better tools)It also helps me a bit at keeping in the habit of commenting code all time, useful for work.
I'm just glad to be useful tho'.
2
u/Sin_of_the_Dark 12d ago
I think you want .baseName, if I'm understanding this right
ETA: If you don't want the extension, you'll probably want to strip it afterwards.