I have this script that does not apply correctly to the subfolders. It should create the files all inside the folder "Txt_ENG" respecting the subfolders.
Example:
I am in:
G:\Games\Files here
the file abc.csv is located in:
G:\Games\Files here\current\csv
the file abc.txt needs to be created in:
G:\Games\Files here\Txt_ENG\current\csv
Where it creates it to me:
G:\Games\Files here\Txt_ENG\Games\Files here\current\csv
Code:
param(
$FileName = '*.csv', # File-name filter
$SourceDir = $PWD, # Input-files dir.
$OutDir = $PWD, # Output-files dir.
$ColumnIndex = 3, # 1-based index of the col. of interest
$OutFileBaseNameSuffix = "_column$ColumnIndex"
)
# Define the destination folder
$destinationFolder = Join-Path -Path $OutDir -ChildPath "Txt_ENG"
# Create the destination folder if it doesn't exist already
if (-not (Test-Path -Path $destinationFolder)) {
New-Item -Path $destinationFolder -ItemType Directory | Out-Null
}
foreach ($csvFile in Get-ChildItem -LiteralPath $SourceDir -Recurse -Filter $FileName -File) {
# Import all rows from the current file
$rows = Import-Csv $csvFile.FullName
# Determine the name of the column of interest with the specified index.
# Subtract -1 from $ColumnIndex since array indices start from *0*.
$colName = ($rows[0].psobject.Properties.Name)[$ColumnIndex-1]
# Construct the destination path while maintaining the subfolder structure
$relativePath = $csvFile.FullName.Substring($SourceDir.Length + 1)
$destinationPath = Join-Path -Path $destinationFolder -ChildPath $relativePath
# Create the destination folder if it doesn't exist already
$destinationDirectory = Split-Path -Path $destinationPath -Parent
if (-not (Test-Path -Path $destinationDirectory)) {
New-Item -Path $destinationDirectory -ItemType Directory | Out-Null
}
# Determine the output file path and name
$outFile = Join-Path $destinationDirectory ('{0}.txt' -f $csvFile.BaseName)
# Write the entire file, as UTF-8 without BOM
$null =
Set-Content -Path $outFile -Value (
$colName + "`n" + ($rows.$colName -join "`n") + "`n"
) -Encoding UTF8
}
$SourceDir.Length
is wrong, $PWD
is an object of type PathInfo
not a string. Its .Length
will be 1
, so:
# using C:\ instead of G:\ to avoid error
$destination = 'C:\Games\Files here\Txt_ENG'
$filePath = 'C:\Games\Files here\current\csv\abc.csv'
Join-Path $destination $filePath.Substring(1 + 1)
# Outputs the unexpected path:
# C:\Games\Files here\Txt_ENG\Games\Files here\current\csv\abc.csv
What you meant to do is $SourceDir.Path.Length + 1
or $SourceDir.ToString().Length + 1
:
$relativePath = $csvFile.FullName.Substring($SourceDir.Path.Length + 1)