Powershell - Move files with certain date, extension and keep atleast one file - list

So I need to create Powershell script where the script first checks that the file suffix is correct. In example it could be just ".txt", then it does check that the first two letter in file name is correct (in example AA and BB). After that it checks if the file is older than one month, if so, the file moves from A to B, but if there is only one file in the directory with the first two letters (BB) it will stay untouched and if there is let's say 20 files (CC) that are all older than one month it will move all except 1 and it needs to be the newest file.
I truly have no idea how this type of script should be done.. I have only done a very simple scripts.
Thanks for you help in advance.

Assuming source and destination folder exist, you can do:
$source = "C:\temp\location1"
$destination = "C:\temp\location2"
$filter = "AA*.txt"
Get-ChildItem -Filter $filter $source `
| Sort-Object -Property LastWriteTime `
| Where-Object { MonthDifference $(Get-Date).DateTime $_.LastWriteTime.DateTime -gt 1 } `
| Select-Object -Skip 1 `
| ForEach-Object { Move-Item $_.FullName $destination }
function MonthDifference([System.DateTime] $dateLeft, [System.DateTime] $dateRight)
{
return ($dateLeft.Month - $dateRight.Month) + 12 * ($dateLeft.Year - $dateRight.Year)
}

Derloopkat gave you a good approach. Yet, since you said...
'I truly have no idea how this type of script should be done...'
... this would mean you need to spend the needed time ramp-up of PowerShell (because you may not fully grasp what respondents will provide, thus engendering more questions.) and learning to step-thru needed logic. So, as I said, you are showing at minimum 7 steps to clear before any of the optimizations which 'derloopkat' is showing, then this. I am using a simplified date selection vs the function 'derlookat' provided. You need to decide which works for your use case/goal.
In any case, not knowing how to check yourself before you execute any code is paramount. Never run anyone's code, especially destructive code (New. Create, Update, Modify, Delete, Move...); as you can destroy your environment if you don't have a backup; unless you fully understand what it's is doing, or be willing to accept the consequences of using it. This is why the -WhatIf parameter, for the command that supports it, exists.
<#
1 - the script first checks that the file suffix is correct.
In example it could be just ".txt",
#>
Get-ChildItem -Path 'D:\Temp' -Filter '*.txt'
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10-Jan-20 17:59 0 awél.txt
-a---- 15-Oct-20 14:47 1074 Book- Copy (2).txt
-a---- 14-Oct-20 16:45 71 book1 - Copy - Copy.txt
...
...
#>
<#
2 - then it does check that the first two letter in file name is correct (in example AA and BB).
#>
Get-ChildItem -Path 'D:\Temp' -Filter '*.txt' |
ForEach-Object {
If ($PSItem.Name -Like 'Da*' -or $PSItem.Name -Like 'bo*')
{$PSItem}
}
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15-Oct-20 14:47 1074 Book- Copy (2).txt
-a---- 14-Oct-20 16:45 71 book1 - Copy - Copy.txt
-a---- 14-Oct-20 16:45 71 book1 - Copy.txt
-a---- 14-Oct-20 16:45 71 book1.txt
-a---- 20-Feb-20 16:01 644 Book2 - Copy.txt
-a---- 20-Feb-20 16:01 644 Book2.txt
-a---- 20-Feb-20 16:01 644 Books1.txt
-a---- 15-Oct-20 14:47 1074 DataFile - Copy - Copy.txt
-a---- 15-Oct-20 14:47 1074 DataFile - Copy.txt
-a---- 15-Oct-20 14:47 1074 DataFile.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData.txt
#>
<#
3 - After that it checks if the file is older than one month,
#>
Get-ChildItem -Path 'D:\Temp' -Filter '*.txt' |
ForEach-Object {
If ($PSItem.Name -Like 'Da*' -or $PSItem.Name -Like 'bo*')
{
$PSItem |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1)
# Or
# Where-Object -Property LastWriteTime -LT (Get-Date).AddDays(-30) or whatever formula you'd want to use.
}
}
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 20-Feb-20 16:01 644 Book2 - Copy.txt
-a---- 20-Feb-20 16:01 644 Book2.txt
-a---- 20-Feb-20 16:01 644 Books1.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData.txt
#>
<#
if so,
4 - the file moves from A to B,
#>
Get-ChildItem -Path 'D:\Temp' -Filter '*.txt' |
ForEach-Object {
If ($PSItem.Name -Like 'Da*' -or $PSItem.Name -Like 'bo*')
{
$PSItem |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1) |
Move-Item -Destination D:\Temp1 -WhatIf
}
}
# Results
<#
What if: Performing the operation "Move File" on target "Item: D:\Temp\Book2 - Copy.txt Destination: D:\Temp1\Book2 - Copy.txt".
What if: Performing the operation "Move File" on target "Item: D:\Temp\Book2.txt Destination: D:\Temp1\Book2.txt".
What if: Performing the operation "Move File" on target "Item: D:\Temp\Books1.txt Destination: D:\Temp1\Books1.txt".
What if: Performing the operation "Move File" on target "Item: D:\Temp\DateData - Copy - Copy.txt Destination: D:\Temp1\DateData - Copy - Copy.txt".
What if: Performing the operation "Move File" on target "Item: D:\Temp\DateData - Copy.txt Destination: D:\Temp1\DateData - Copy.txt".
What if: Performing the operation "Move File" on target "Item: D:\Temp\DateData.txt Destination: D:\Temp1\DateData.txt".
#>
<#
5 - but if there is only one file in the directory with the first two letters (BB) it will stay untouched
#>
Get-ChildItem -Path 'D:\Temp' -Filter '*.txt' |
Sort-Object -Property LastWriteTIme, Name |
ForEach-Object {
If ($PSItem.Name -Like 'Da*' -or $PSItem.Name -Like 'bo*')
{
$PSItem |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1) |
Select-Object -Skip 1
}
}
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 20-Feb-20 16:01 644 Book2 - Copy.txt
-a---- 20-Feb-20 16:01 644 Book2.txt
-a---- 20-Feb-20 16:01 644 Books1.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData.txt
#>
<#
6 - and if there is let's say 20 files (CC) that are all older than one month
it will move all except 1 and it needs to be the newest file.
#>
# Assuming source and destination folder exist, you can do:
$source = 'D:\temp'
$destination = 'D:\temp1'
$filter = 'Da*', 'bo*', 'Em*'
Get-ChildItem -Filter $filter $source `
| Sort-Object -Property LastWriteTime `
| Where-Object { MonthDifference $(Get-Date).DateTime $PSitem.LastWriteTime.DateTime -gt 1 } `
| Select-Object -Skip 1 `
| ForEach-Object { Move-Item $PSitem.FullName $destination -WhatIf}
function MonthDifference([System.DateTime] $dateLeft, [System.DateTime] $dateRight)
{return ($dateLeft.Month - $dateRight.Month) + 12 * ($dateLeft.Year - $dateRight.Year)}
# then step thru to see how to get to your final use case
Clear-Host
$FileSource = 'D:\temp'
$FileDestination = 'D:\temp1'
($MoveFileTargets = 'Da*', 'bo*', 'Em*' |
ForEach {
Get-ChildItem -Path 'D:\Temp' -Filter "$PSItem.txt" |
Sort-Object -Property LastWriteTime |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1)
})
"Total Files: $($MoveFileTargets.Count)"
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 20-Feb-20 16:01 644 DateData - Copy - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData.txt
-a---- 20-Feb-20 16:01 644 Book2 - Copy.txt
-a---- 20-Feb-20 16:01 644 Book2.txt
-a---- 20-Feb-20 16:01 644 Books1.txt
-a---- 04-May-20 14:54 566 EmailData - Copy - Copy.txt
-a---- 04-May-20 14:54 566 EmailData - Copy.txt
-a---- 04-May-20 14:54 566 EmailData.txt
Total Files: 9
#>
Clear-Host
$FileSource = 'D:\temp'
$FileDestination = 'D:\temp1'
($MoveFileTargets = 'Da*', 'bo*', 'Em*' |
ForEach {
Get-ChildItem -Path $FileSource -Filter "$PSItem.txt" |
Sort-Object -Property LastWriteTime |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1) |
Select-Object -Skip 1
})
"Move Files: $($MoveFileTargets.Count)"
# Results
<#
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 20-Feb-20 16:01 644 DateData - Copy.txt
-a---- 20-Feb-20 16:01 644 DateData.txt
-a---- 20-Feb-20 16:01 644 Book2.txt
-a---- 20-Feb-20 16:01 644 Books1.txt
-a---- 04-May-20 14:54 566 EmailData - Copy.txt
-a---- 04-May-20 14:54 566 EmailData.txt
Move Files: 6
#>
Clear-Host
$FileSource = 'D:\temp'
$FileDestination = 'D:\temp1'
($MoveFileTargets = 'Da*', 'bo*', 'Em*' |
ForEach {
Get-ChildItem -Path $FileSource -Filter "$PSItem.txt" |
Sort-Object -Property LastWriteTime |
Where-Object -Property LastWriteTime -LT (Get-Date).AddMonths(-1) |
Select-Object -Skip 1 |
Move-Item -Destination $FileDestination -WhatIf
})
# Results
<#
What if: Performing the operation "Move File" on target "Item: D:\temp\DateData - Copy.txt Destination: D:\temp1\DateData - Copy.txt".
What if: Performing the operation "Move File" on target "Item: D:\temp\DateData.txt Destination: D:\temp1\DateData.txt".
What if: Performing the operation "Move File" on target "Item: D:\temp\Book2.txt Destination: D:\temp1\Book2.txt".
What if: Performing the operation "Move File" on target "Item: D:\temp\Books1.txt Destination: D:\temp1\Books1.txt".
What if: Performing the operation "Move File" on target "Item: D:\temp\EmailData - Copy.txt Destination: D:\temp1\EmailData - Copy.txt".
What if: Performing the operation "Move File" on target "Item: D:\temp\EmailData.txt Destination: D:\temp1\EmailData.txt".
#>
So, all the steps are really just this:
Get a list of all files by a 2 char prefix sorted ascending by the prefix and
latest date.
Exclude the most recent file by date of the list for each 2 char prefix
Move the legacy files to another folder.

First get list of all files starting with let's say AA
$time=(get-date).adddays(-30)
$AA=#(Get-ChildItem AA*.txt | Where-Object {$_LastWriteTime -lt $time})
If there was no files within the last 30 days then get the newest file and set variable $AA to the newest file
if ($AA.length -eq 0) {
$AA=Get-ChildItem AA*.txt | sort $_LastWriteTime | select -first 1
}
The last step is moving files to the destination folder
foreach ($aa_file in $AA){move-item -path $aa_file -destination C:\test_des}

Related

Privileges problem UMASK Nautilus. CentOS 7.7

I have a problem with the privileges of [files/folders] created by Nautilus. As a test I set the UMASK of my specific user to 0000:
[simone#MYPC:~] >cat /mnt/home/simone/.bashrc | grep mask
# User Umask Override
umask 0000
[simone#MYPC:~] >cat /mnt/home/simone/.bashrc
# $HOME/.bashrc
umask 0000
[simone#MYPC:~] >umask
000
When I write a file or folder passing from terminal I can do it with the required privileges:
[simone#MYPC:~/Desktop] >touch file1.txt
[simone#MYPC:~/Desktop] >mkdir Folder1
[simone#MYPC:~/Desktop] >ls -la
-rw-rw-rw-. 1 simone home 0 Mar 21 2022 file1.txt
drwxrwxrwx. 2 simone home 4096 Mar 21 2022 Folder1
But when I create a file (TextEditor) or folder through Nautilus, I get different privileges:
[simone#MYPC:~] >ls -lart /tmp
drwxr-xr-x. 1 simone home 0 Mar 18 10:04 FolderByNautilus
[simone#MYPC:~] > ls -la /tmp/fileNautilus.txt
-rw-r--r--. 1 simone home 5 Mar 11 2022 /tmp/fileNautilus.txt
I would like Nautilus or text editor to write with the mask 0000 leaving the same privileges with which my terminal writes

How do I use grep -Po regex options to match across multiple lines without being greedy?

I would like to capture only successful nmap scan results and exclude results that did not return useful information. I've listed my desired grep output below that I want.
I tried using (?s) to enable DOTALL to make . include line breaks so that I can match/capture across multiple lines, but the problem is that it appears to disable the use of \n which I want to use as part of my pattern.
I'm trying to use a lookahead but I know the .* is greedy and I think it's matching the longest string which is basically the entire file. I want it to use the shortest string instead.
How can I dynamically capture successful nmap scan results in the following text file using Grep's -Po regex options?
desired output:
Nmap scan report for 10.11.1.72
Host is up (0.028s latency).
PORT STATE SERVICE
111/tcp open rpcbind
| nfs-ls: Volume /home
| access: Read Lookup NoModify NoExtend NoDelete NoExecute
| PERMISSION UID GID SIZE TIME FILENAME
| drwxr-xr-x 0 0 4096 2015-09-17T13:21:59 .
| drwxr-xr-x 0 0 4096 2015-01-07T10:56:34 ..
| drwxr-xr-x 1013 1013 4096 2015-09-17T13:21:47 jenny
| drwxr-xr-x 1012 1012 4096 2015-09-17T13:21:40 joe45
| drwxr-xr-x 1011 1011 4096 2015-09-17T13:21:52 john
| drwxr-xr-x 1014 1014 4096 2019-10-27T23:48:51 marcus
| drwxr-x--- 0 1010 4096 2015-01-08T16:01:31 ryuu
|_
| nfs-showmount:
|_ /home 10.11.0.0/255.255.0.0
| nfs-statfs:
| Filesystem 1K-blocks Used Available Use% Maxfilesize Maxlink
|_ /home 7223800.0 2059608.0 4797244.0 31% 8.0T 32000
Here is my current command that I'm starting with:
grep -Poz '(?s)\d+\.\d+\.\d+\.\d+.*Nmap' test2
test2 file:
### SCAN RESULTS ###
Nmap scan report for 10.11.1.39
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp filtered rpcbind
Nmap scan report for 10.11.1.44
Host is up (0.043s latency).
PORT STATE SERVICE
111/tcp closed rpcbind
Nmap scan report for 10.11.1.50
Host is up (0.043s latency).
PORT STATE SERVICE
111/tcp filtered rpcbind
Nmap scan report for 10.11.1.71
Host is up (0.040s latency).
PORT STATE SERVICE
111/tcp closed rpcbind
Nmap scan report for 10.11.1.72
Host is up (0.040s latency).
PORT STATE SERVICE
111/tcp open rpcbind
| nfs-ls: Volume /home
| access: Read Lookup NoModify NoExtend NoDelete NoExecute
| PERMISSION UID GID SIZE TIME FILENAME
| drwxr-xr-x 0 0 4096 2015-09-17T13:21:59 .
| drwxr-xr-x 0 0 4096 2015-01-07T10:56:34 ..
| drwxr-xr-x 1013 1013 4096 2015-09-17T13:21:47 jenny
| drwxr-xr-x 1012 1012 4096 2015-09-17T13:21:40 joe45
| drwxr-xr-x 1011 1011 4096 2015-09-17T13:21:52 john
| drwxr-xr-x 1014 1014 4096 2019-10-27T23:48:51 marcus
| drwxr-x--- 0 1010 4096 2015-01-08T16:01:31 ryuu
|_
| nfs-showmount:
|_ /home 10.11.0.0/255.255.0.0
| nfs-statfs:
| Filesystem 1K-blocks Used Available Use% Maxfilesize Maxlink
|_ /home 7223800.0 2068516.0 4788336.0 31% 8.0T 32000
Nmap scan report for 10.11.1.73
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp filtered rpcbind
Nmap scan report for 10.11.1.75
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp filtered rpcbind
Nmap scan report for 10.11.1.79
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp filtered rpcbind
Nmap scan report for 10.11.1.101
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp closed rpcbind
Use a non-greedy quantifier followed by a lookahead.
grep -Poz '(?s)\d+\.\d+\.\d+\.\d+.*?(?=Nmap)' test2
Finally figured out how to do this, probably not the prettiest way of doing it but it works...
command:
grep -Poz 'Nmap scan report.+\nHost is up.+\n\nPORT.+\n\d+.+\n\|(.|\n)+?(?=\n\n)' test2
output:
Nmap scan report for 10.11.1.72
Host is up (0.041s latency).
PORT STATE SERVICE
111/tcp open rpcbind
| nfs-ls: Volume /home
| access: Read Lookup NoModify NoExtend NoDelete NoExecute
| PERMISSION UID GID SIZE TIME FILENAME
| drwxr-xr-x 0 0 4096 2015-09-17T13:21:59 .
| drwxr-xr-x 0 0 4096 2015-01-07T10:56:34 ..
| drwxr-xr-x 1013 1013 4096 2015-09-17T13:21:47 jenny
| drwxr-xr-x 1012 1012 4096 2015-09-17T13:21:40 joe45
| drwxr-xr-x 1011 1011 4096 2015-09-17T13:21:52 john
| drwxr-xr-x 1014 1014 4096 2019-10-27T23:48:51 marcus
| drwxr-x--- 0 1010 4096 2015-01-08T16:01:31 ryuu
|_
| nfs-showmount:
|_ /home 10.11.0.0/255.255.0.0
| nfs-statfs:
| Filesystem 1K-blocks Used Available Use% Maxfilesize Maxlink
|_ /home 7223800.0 2059600.0 4797252.0 31% 8.0T 32000
notes:
had to specify unique filter for first 5 lines to exclude unsuccessful scans
it's important to use -z as this allows for matching \n
it was necessary to use OR expression (.|\n)*? to match all text across multiple lines
used a lookahead (?=\n\n) to specify end of match
make sure to use +? to make modifier non-greedy so that it matches the shortest string instead of longest string

PortAudio Test application - Unresolved External symbol Pa_GetVersionInfo

Background
I downloaded https://github.com/PortAudio/portaudio and compiled a DLL (removed ASIO support).
I'm running windows 10...Visual Studio 2019. Using the files in the msvc folder, I created a 64bit dll. under the build/msvc/ folder it created a new x64/release subfolder, and I see the following files:
cp#DESKTOP-ESLJ8N0:/mnt/c/Users/cp/source/github/portaudio/build/msvc/x64/Release$ ls -lah
total 3.8M
drwxrwxrwx 1 cp cp 4.0K Oct 6 14:56 .
drwxrwxrwx 1 cp cp 4.0K Oct 6 14:56 ..
-rwxrwxrwx 1 cp cp 13K Oct 6 14:56 pa_allocation.obj
-rwxrwxrwx 1 cp cp 118K Oct 6 14:56 pa_converters.obj
-rwxrwxrwx 1 cp cp 5.3K Oct 6 14:56 pa_cpuload.obj
-rwxrwxrwx 1 cp cp 5.3K Oct 6 14:56 pa_debugprint.obj
-rwxrwxrwx 1 cp cp 3.0K Oct 6 14:56 pa_dither.obj
-rwxrwxrwx 1 cp cp 66K Oct 6 14:56 pa_front.obj
-rwxrwxrwx 1 cp cp 21K Oct 6 14:56 pa_hostapi_skeleton.obj
-rwxrwxrwx 1 cp cp 60K Oct 6 14:56 pa_process.obj
-rwxrwxrwx 1 cp cp 14K Oct 6 14:56 pa_ringbuffer.obj
-rwxrwxrwx 1 cp cp 7.1K Oct 6 14:56 pa_stream.obj
-rwxrwxrwx 1 cp cp 2.0K Oct 6 14:56 pa_trace.obj
-rwxrwxrwx 1 cp cp 17K Oct 6 14:56 pa_win_coinitialize.obj
-rwxrwxrwx 1 cp cp 190K Oct 6 14:56 pa_win_ds.obj
-rwxrwxrwx 1 cp cp 25K Oct 6 14:56 pa_win_ds_dynlink.obj
-rwxrwxrwx 1 cp cp 1.5K Oct 6 14:56 pa_win_hostapis.obj
-rwxrwxrwx 1 cp cp 18K Oct 6 14:56 pa_win_util.obj
-rwxrwxrwx 1 cp cp 664K Oct 6 14:56 pa_win_wasapi.obj
-rwxrwxrwx 1 cp cp 19K Oct 6 14:56 pa_win_waveformat.obj
-rwxrwxrwx 1 cp cp 344K Oct 6 14:56 pa_win_wdmks.obj
-rwxrwxrwx 1 cp cp 29K Oct 6 14:56 pa_win_wdmks_utils.obj
-rwxrwxrwx 1 cp cp 154K Oct 6 14:56 pa_win_wmme.obj
-rwxrwxrwx 1 cp cp 1.3K Oct 6 14:56 pa_x86_plain_converters.obj
-rwxrwxrwx 1 cp cp 0 Oct 6 14:56 portaudio.Build.CppClean.log
-rwxrwxrwx 1 cp cp 287 Oct 6 14:56 portaudio.dll.recipe
-rwxrwxrwx 1 cp cp 3.4K Oct 6 14:56 portaudio.log
drwxrwxrwx 1 cp cp 4.0K Oct 6 14:56 portaudio.tlog
-rwxrwxrwx 1 cp cp 0 Oct 6 14:56 portaudio.vcxproj.FileListAbsolute.txt
-rwxrwxrwx 1 cp cp 214K Oct 6 14:56 portaudio_x64.dll
-rwxrwxrwx 1 cp cp 7.4K Oct 6 14:56 portaudio_x64.exp
-rwxrwxrwx 1 cp cp 13K Oct 6 14:56 portaudio_x64.lib
-rwxrwxrwx 1 cp cp 1.5M Oct 6 14:56 portaudio_x64.pdb
-rwxrwxrwx 1 cp cp 268K Oct 6 14:56 vc142.pdb
cp#DESKTOP-ESLJ8N0:/mnt/c/Users/cp/source/github/portaudio/build/msvc/x64/Release$
Cool. So far so good.
Next, I create a console application to try to test the DLL. So specifically I:
Specifically, I want to do something like this:
https://github.com/PortAudio/portaudio/blob/master/examples/pa_devs.c
I started by doing the following:
a) create a windows console application called "portaudio-listdevices-command". it creates a "hello world" solution. it compiles and runs no problem.
b) I hijacked the default "ConsoleApplication1.cpp" file and tried to copy all the logic from pa_devs.c into this cpp file. The code in the cpp file looks like this:
https://github.com/closetcodebrews/portaudio-listdevices-commandline/blob/main/ConsoleApplication1/ConsoleApplication1.cpp
c) I copied all the header files from the portaudio solution directly into my client application folder.
In case it helps, this is what the folder structure looks like for the client application:
cp#DESKTOP-ESLJ8N0:/mnt/c/Users/cp/source/github/portaudio-listdevices-command/ConsoleApplication1$ ls -lah
total 156K
drwxrwxrwx 1 cp cp 4.0K Oct 7 08:16 .
drwxrwxrwx 1 cp cp 4.0K Oct 6 15:34 ..
drwxrwxrwx 1 cp cp 4.0K Oct 6 15:34 .vs
-rwxrwxrwx 1 cp cp 8.1K Oct 6 17:00 ConsoleApplication1.cpp
-rwxrwxrwx 1 cp cp 1.5K Oct 6 15:34 ConsoleApplication1.sln
-rwxrwxrwx 1 cp cp 7.9K Oct 7 08:29 ConsoleApplication1.vcxproj
-rwxrwxrwx 1 cp cp 992 Oct 6 15:34 ConsoleApplication1.vcxproj.filters
-rwxrwxrwx 1 cp cp 168 Oct 6 15:34 ConsoleApplication1.vcxproj.user
drwxrwxrwx 1 cp cp 4.0K Oct 7 08:05 Debug
-rwxrwxrwx 1 cp cp 5.8K Oct 6 13:24 pa_asio.h
-rwxrwxrwx 1 cp cp 2.9K Oct 6 13:24 pa_jack.h
-rwxrwxrwx 1 cp cp 3.9K Oct 6 13:24 pa_linux_alsa.h
-rwxrwxrwx 1 cp cp 7.6K Oct 6 13:24 pa_mac_core.h
-rwxrwxrwx 1 cp cp 3.5K Oct 6 13:24 pa_win_ds.h
-rwxrwxrwx 1 cp cp 24K Oct 6 13:24 pa_win_wasapi.h
-rwxrwxrwx 1 cp cp 8.9K Oct 6 13:24 pa_win_waveformat.h
-rwxrwxrwx 1 cp cp 5.0K Oct 6 13:24 pa_win_wdmks.h
-rwxrwxrwx 1 cp cp 6.9K Oct 6 13:24 pa_win_wmme.h
-rwxrwxrwx 1 cp cp 48K Oct 6 13:24 portaudio.h
drwxrwxrwx 1 cp cp 4.0K Oct 7 08:16 x64
cp#DESKTOP-ESLJ8N0:/mnt/c/Users/cp/source/github/portaudio-listdevices-command/ConsoleApplication1$
Problem
When I try to compile the client application, this is the error I'm getting:
Error LNK2019 unresolved external symbol Pa_GetVersionInfo referenced in function main ConsoleApplication1 C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\ConsoleApplication1.obj 1
What I've tried so far:
I've modified the following properties in my project:
Project --> Properties --> Linker --> Input --> Additional Dependencies --> "portaudio_x64.lib"
Project --> Properties --> VC++ Directories --> Library Directories --> c:\Users\cp\source\github\portaudio\build\msvc\x64\Release
Header files were just copied from the portaudio source folder direct to the client application so now I have this:
For what it's worth, in my ConsoleApplication1.cpp file, when I hover over the call to Pa_GetVersion() it does give me contextual help and shows me what the function does. Does this prove that the lib file is working?
Any help would be appreciated.
**DUMPBIN RESULTS **
PS C:\Users\cp\source\github\portaudio\build\msvc\x64\Release> dumpbin /exports portaudio_x64.dll
Microsoft (R) COFF/PE Dumper Version 14.27.29111.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file portaudio_x64.dll
File Type: DLL
Section contains the following exports for portaudio_x64.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
68 number of functions
48 number of names
ordinal hint RVA name
52 0 0001CE10 PaUtil_InitializeX86PlainConverters = PaUtil_InitializeX86PlainConverters
55 1 00003110 PaUtil_SetDebugPrintFunction = PaUtil_SetDebugPrintFunction
56 2 0000D100 PaWasapi_GetAudioClient = PaWasapi_GetAudioClient
58 3 0000D140 PaWasapi_GetDeviceCurrentFormat = PaWasapi_GetDeviceCurrentFormat
59 4 0000D1A0 PaWasapi_GetDeviceDefaultFormat = PaWasapi_GetDeviceDefaultFormat
60 5 0000D270 PaWasapi_GetDeviceMixFormat = PaWasapi_GetDeviceMixFormat
61 6 0000D340 PaWasapi_GetDeviceRole = PaWasapi_GetDeviceRole
64 7 0000D3C0 PaWasapi_GetFramesPerHostBuffer = PaWasapi_GetFramesPerHostBuffer
65 8 0000D3F0 PaWasapi_GetJackCount = PaWasapi_GetJackCount
66 9 0000D5D0 PaWasapi_GetJackDescription = PaWasapi_GetJackDescription
67 A 0000DAA0 PaWasapi_SetDefaultInterfaceId = PaWasapi_SetDefaultInterfaceId
68 B 0000DAB0 PaWasapi_SetStreamStateHandler = PaWasapi_SetStreamStateHandler
62 C 0000DAD0 PaWasapi_ThreadPriorityBoost = PaWasapi_ThreadPriorityBoost
63 D 0000DB10 PaWasapi_ThreadPriorityRevert = PaWasapi_ThreadPriorityRevert
23 E 00003520 Pa_AbortStream = Pa_AbortStream
19 F 00003570 Pa_CloseStream = Pa_CloseStream
7 10 000035D0 Pa_GetDefaultHostApi = Pa_GetDefaultHostApi
13 11 00003600 Pa_GetDefaultInputDevice = Pa_GetDefaultInputDevice
14 12 00003630 Pa_GetDefaultOutputDevice = Pa_GetDefaultOutputDevice
12 13 00003660 Pa_GetDeviceCount = Pa_GetDeviceCount
15 14 00003680 Pa_GetDeviceInfo = Pa_GetDeviceInfo
3 15 000036C0 Pa_GetErrorText = Pa_GetErrorText
6 16 00003870 Pa_GetHostApiCount = Pa_GetHostApiCount
8 17 00003890 Pa_GetHostApiInfo = Pa_GetHostApiInfo
11 18 000038C0 Pa_GetLastHostErrorInfo = Pa_GetLastHostErrorInfo
33 19 000038D0 Pa_GetSampleSize = Pa_GetSampleSize
28 1A 00003950 Pa_GetStreamCpuLoad = Pa_GetStreamCpuLoad
26 1B 00003980 Pa_GetStreamInfo = Pa_GetStreamInfo
31 1C 000039B0 Pa_GetStreamReadAvailable = Pa_GetStreamReadAvailable
27 1D 000039E0 Pa_GetStreamTime = Pa_GetStreamTime
32 1E 00003A10 Pa_GetStreamWriteAvailable = Pa_GetStreamWriteAvailable
1 1F 00003A40 Pa_GetVersion = Pa_GetVersion
2 20 00003A60 Pa_GetVersionText = Pa_GetVersionText
10 21 00003A70 Pa_HostApiDeviceIndexToDeviceIndex = Pa_HostApiDeviceIndexToDeviceIndex
9 22 00003AC0 Pa_HostApiTypeIdToHostApiIndex = Pa_HostApiTypeIdToHostApiIndex
4 23 00003B10 Pa_Initialize = Pa_Initialize
16 24 00003B50 Pa_IsFormatSupported = Pa_IsFormatSupported
25 25 00003C80 Pa_IsStreamActive = Pa_IsStreamActive
24 26 00003CB0 Pa_IsStreamStopped = Pa_IsStreamStopped
18 27 00003CE0 Pa_OpenDefaultStream = Pa_OpenDefaultStream
17 28 00003DF0 Pa_OpenStream = Pa_OpenStream
29 29 00003FB0 Pa_ReadStream = Pa_ReadStream
20 2A 00004050 Pa_SetStreamFinishedCallback = Pa_SetStreamFinishedCallback
34 2B 0001C700 Pa_Sleep = Pa_Sleep
21 2C 000040A0 Pa_StartStream = Pa_StartStream
22 2D 000040F0 Pa_StopStream = Pa_StopStream
5 2E 00004140 Pa_Terminate = Pa_Terminate
30 2F 00004180 Pa_WriteStream = Pa_WriteStream
Summary
3000 .data
7000 .pdata
24000 .rdata
1000 .reloc
1000 .rsrc
6B000 .text
1000 _RDATA
Detailed Output from Link.exe
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe" /INCREMENTAL /NOLOGO portaudio_x64.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FASTLINK /PDB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.lib" /MACHINE:X64 x64\Debug\ConsoleApplication1.obj
1> Tracking command:
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\Tracker.exe /a /d "C:\Program Files (x86)\MSBuild\15.0\FileTracker\FileTracker32.dll" /i C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleA.8f735e32.tlog /r C:\USERS\cp\SOURCE\GITHUB\PORTAUDIO-LISTDEVICES-COMMAND\CONSOLEAPPLICATION1\X64\DEBUG\CONSOLEAPPLICATION1.OBJ /b MSBuildConsole_CancelEventca601256d110470b96dcd6bd48d0231f /c "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\link.exe" /ERRORREPORT:PROMPT /OUT:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe" /INCREMENTAL /NOLOGO portaudio_x64.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FASTLINK /PDB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.lib" /MACHINE:X64 x64\Debug\ConsoleApplication1.obj
Additional Lib Path now Defined
Latest Link Errors
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe" /INCREMENTAL /NOLOGO /LIBPATH:C:\Users\cp\source\github\portaudio\build\msvc\x64\Release /LIBPATH:C:\Users\cp\source\github\portaudio\build\msvc\x64\Release portaudio_x64.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FASTLINK /PDB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.lib" /MACHINE:X64 x64\Debug\ConsoleApplication1.obj
1> Tracking command:
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\Tracker.exe /a /d "C:\Program Files (x86)\MSBuild\15.0\FileTracker\FileTracker32.dll" /i C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleA.8f735e32.tlog /r C:\USERS\cp\SOURCE\GITHUB\PORTAUDIO-LISTDEVICES-COMMAND\CONSOLEAPPLICATION1\X64\DEBUG\CONSOLEAPPLICATION1.OBJ /b MSBuildConsole_CancelEventa9f191895925491f926a123cade0b276 /c "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.27.29110\bin\HostX86\x64\link.exe" /ERRORREPORT:PROMPT /OUT:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe" /INCREMENTAL /NOLOGO /LIBPATH:C:\Users\cp\source\github\portaudio\build\msvc\x64\Release /LIBPATH:C:\Users\cp\source\github\portaudio\build\msvc\x64\Release portaudio_x64.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FASTLINK /PDB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.lib" /MACHINE:X64 x64\Debug\ConsoleApplication1.obj
1> ConsoleApplication1.obj : error LNK2019: unresolved external symbol Pa_GetVersionInfo referenced in function main
1> C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe : fatal error LNK1120: 1 unresolved externals
1> The command exited with code 1120.
1> Done executing task "Link" -- FAILED.
1>Done building target "Link" in project "ConsoleApplication1.vcxproj" -- FAILED.
1>
1>Done building project "ConsoleApplication1.vcxproj" -- FAILED.
1>
1>Build FAILED.
1>
1>ConsoleApplication1.obj : error LNK2019: unresolved external symbol Pa_GetVersionInfo referenced in function main
1>C:\Users\cp\source\github\portaudio-listdevices-command\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe : fatal error LNK1120: 1 unresolved externals
1> 0 Warning(s)
1> 2 Error(s)
So I can't take credit for this. I'm only posting answer so we can close this question.
But the issue was with the portaudio library itself
The portinfo.def file was not exporting the method that I was trying to call - the method referenced in the example file.
the fix was to add the following line to the portinfo.def file:
Pa_GetVersionInfo # 69
Now my client / console app compiles.
I will submit a patch later today to portaudio repo for the community to consider. But thanks to #HansPassant and πάντα ῥεῖ

Bash, need to change word order in multiple directories

I have a considerable classical FLAC collection where each album is a directory. I've realized that I have used a sub-optimal structure and need to rename all the directories.
My current naming convention is:
COMPOSER (CONDUCTOR) - NAME OF PIECE
E.g.
"Bach (Celibidache) - Mass in F minor"
I want to change the naming to
COMPOSER - NAME OF PIECE (CONDUCTOR)
I.e.
"Bach - Mass in F minor (Celibidache)"
There are some possible exceptions, the (CONDUCTOR) may be (CONDUCTOR, SOLOIST) and some directories do not have the (CONDUCTOR) part and should be left as is. The NAME OF PIECE can contain all legal letters and symbols.
All albums are located in the same parent directory, so no sub-directories.
What is the easy way to do this?
use perl rename (some distributions have this as rename - Ubuntu and related, some as prename - Fedora and Redhat AFAIK). Check first.
prename -n -- '-d && s/(\(.*\)) - (.*)/- \2 \1/' *
-n don't rename just print the results - remove after you are ok with the results.
-- end of the options, start of the perlexpr and files
-d check that the file is a directory
s/.../.../ - substitution
Example:
[test01#localhost composers]$ ls -la
total 12
drwxrwxr-x 3 test01 test01 4096 Feb 14 12:37 .
drwxrwxr-x. 7 test01 test01 4096 Feb 14 12:23 ..
drwxrwxr-x 2 test01 test01 4096 Feb 14 12:37 'Bach (Celibidache) - Mass in F minor'
-rw-rw-r-- 1 test01 test01 0 Feb 14 12:27 'Bach (Celibidache) - Mass in F minor.flac'
[test01#localhost composers]$ prename -n -- '-d && s/(\(.*\)) - (.*)/- \2 \1/' *
Bach (Celibidache) - Mass in F minor -> Bach - Mass in F minor (Celibidache)
[test01#localhost composers]$ prename -- '-d && s/(\(.*\)) - (.*)/- \2 \1/' *
[test01#localhost composers]$ ls -la
total 12
drwxrwxr-x 3 test01 test01 4096 Feb 14 12:38 .
drwxrwxr-x. 7 test01 test01 4096 Feb 14 12:23 ..
-rw-rw-r-- 1 test01 test01 0 Feb 14 12:27 'Bach (Celibidache) - Mass in F minor.flac'
drwxrwxr-x 2 test01 test01 4096 Feb 14 12:37 'Bach - Mass in F minor (Celibidache)'
Note that without -d both the file and the directory would have been renamed.

How can I search for a file using tcl, with only part of the file name

If I have a folder with the following files:
hello-version-1-090.txt
hello-awesome-well-091.txt
goodday-087.txt
hellooo-874.txt
hello_476.txt
hello_094.txt
How can I search for a file which has the term: 'hello' and '091' in it using tcl.
Possible solution:
taking the output of an ls -l in a folder, splitting it with '\n' and then running a foreach on each line and using regexp to match the criteria. But how do I run an ls -l in a folder and record its save its contents (the file names) using tcl?
With glob, you can apply the pattern and can get the list of file names matching our criteria.
puts [ exec ls -l ]; #Just printing the 'ls -l' output
set myfiles [ glob -nocomplain hello*091*.txt ]
if {[llength $myfiles]!=0} {
puts "Following files matched your pattern : "
foreach fname $myfiles {
puts $fname
}
} else {
puts "No files matched your pattern"
}
The reason for using -nocomplain is to allow an empty list to be returned without error if there is no file matched with our search pattern.
Output
sh-4.2# tclsh main.tcl
total 4
-rw-r--r-- 1 root root 0 Mar 4 15:23 goodday-087.txt
-rw-r--r-- 1 root root 0 Mar 4 15:23 hello-awesome-well-091.txt
-rw-r--r-- 1 root root 0 Mar 4 15:23 hello-version-1-090.txt
-rw-r--r-- 1 root root 0 Mar 4 15:23 hello_094.txt
-rw-r--r-- 1 root root 0 Mar 4 15:23 hello_476.txt
-rw-r--r-- 1 root root 0 Mar 4 15:23 hellooo-874.txt
-rw-r--r-- 1 root root 262 Mar 4 15:24 main.tcl
Following files matched your pattern :
hello-awesome-well-091.txt
By the way, with respect to your query on how to save the ls -l output, simply save the output to a variable.
set result [ exec ls -l ]
Then with the result variable, you can apply regexp by means of looping line by line just as you have mentioned.
But, I hope that using glob would be a better approach.
Reference : glob