I would like to remove 'out_' at the beginning of files.
I tried:
get-childitem out_doe*.asc | foreach { rename-item $_ $_.Name.Replace("out_", "") }
bash: syntax error near unexpected token `('
rename "out_*.asc" "////*.asc"
syntax error at (user-supplied code), near "*."
Thank you
How to do that in bash?
Related
this code supposed to look for all demo.txt in the disk and change them from "demo" to "demodemo997182625" and then check if the file has changed or not
$found = 0;
$notfound = 0;
foreach ($file in Get-ChildItem -Path C:\ -Recurse -Filter demo.txt -ErrorAction SilentlyContinue )
{
(Get-Content $file).Replace("demo","demo997182625") | Set-Content $file
$x = (Get-Content $file).contain("demo997182625")
if($x -eq $null){
$found = 1 + $found;
}
else {
$notfound = 1 + $notfound;
}
}
Write-Host "Changed" $found;
Write-Host "Not Changed" $notfound;
A few remarks on your code:
the .Replace() and .Contains() string methods work case-sensitive, so .Replace("demo","demo997182625") won't find and replace "Demo". To have it work case-insensitively, use the -replace operator instead.
updated files can be reprocessed by Get-ChildItem, unless you have that part finish completely first. The easiest way to do that is by enclosing it between brackets
I would only save the file if there was something updated (i.e. the new value was found after -replace), otherwise leave it be
Get-ChildItem returns both FileInfo and DirectoryInfo objects. Since you are interested in changing files only, append the -File switch
best use the FullName property of the found file on the Get- and Set-Content cmdlets instead of the whole FileInfo object
$found = $notfound = 0
# surround the Get-ChildItem line with brackets, so it will finish before iterating on the result
# otherwise, it could reprocess files that were allready updated
foreach ($file in (Get-ChildItem -Path 'C:\' -Recurse -Filter 'demo.txt' -File -ErrorAction SilentlyContinue)) {
# -replace uses regex, so surround the search string with '\b' boundary markers in order to do a whole-word search
$content = (Get-Content -Path $file.FullName -Raw -Force) -replace '\bdemo\b', 'demo997182625'
# test if the content now has the new value (again, use '\b' boundary markers)
if ($content -match '\bdemo997182625\b') {
# save the updated file
$content | Set-Content -Path $file.FullName -Force
$found++
}
else {$notfound++}
}
Write-Host "Changed: $found"
Write-Host "Not Changed: $notfound"
P.S. If your search string contains characters that in regex have special meaning (see table below), you need to escape these with a backslash when using regex operators -replace and -match.
Special Characters in Regex
Char
Description
Meaning
\
Backslash
Used to escape a special character
^
Caret
Beginning of a string
$
Dollar sign
End of a string
.
Period or dot
Matches any single character
|
Vertical bar or pipe symbol
Matches previous OR next character/group
?
Question mark
Match zero or one of the previous
*
Asterisk or star
Match zero, one or more of the previous
+
Plus sign
Match one or more of the previous
( )
Opening and closing parenthesis
Group characters
[ ]
Opening and closing square bracket
Matches a range of characters
{ }
Opening and closing curly brace
Matches a specified number of occurrences of the previous
I have a folder with hundreds of files in the following format:
20210322 - Filename description.txt
20210321 - Filename description.txt
20210320 - Filename description.txt
20210319 - Filename description.txt
20210318 - Filename description.txt
...
Using the Windows Command Prompt, how can I rename them to this format:
20210322 Filename description.txt
20210321 Filename description.txt
20210320 Filename description.txt
20210319 Filename description.txt
20210318 Filename description.txt
...
In other word replace, replace " - " with " ".
In the past, I've used
rename "IMG_*.jpg" "////*.jpg"
To remove "IMG_" from the beginning of filenames. I tried to do something similar, but it didn't work:
rename "* - *.txt" "*/ /.txt"
I found a better solution that works for me. One line, no batch file required. Using Windows Power Shell, enter:
Get-ChildItem -Recurse | ` Where-Object { $_.Name -match " - " } | ` Rename-Item -NewName { $_.Name -replace " - ", " " }
The above command will replace the given text in all filenames, including subfolders and subfiles (recursively).
I hope it's able to help someone.
This is easy enough using a language that is already on supported Windows systems. The -replace will remove the ' - '. When you are satisfied that the files will be renamed correctly, remove the -WhatIf from the Rename-Item command.
powershell.exe -NoLogo -NoProfile -Command ^
"Get-ChildItem -Path '.' -Filter '*.txt' |" ^
"ForEach-Object {" ^
"Rename-Item -Path $_.FullName -NewName $($_.Name -replace ' - ',' ') -WhatIf" ^
"}"
It is easier when run from a PowerShell console or as a .ps1 script.
Get-ChildItem -Path '.' -Filter '*.txt' |
ForEach-Object {
Rename-Item -Path $_.FullName -NewName $($_.Name -replace ' - ',' ') -WhatIf
}
To get a "one-liner," put the first code example above into a file such as Do-Rename.bat saved in a directory mentioned in your PATH variable. Then use a command such as:
Do-Rename
I have about 600 video files with the $ special character in the title.
I want to batch replace this with a letter s.
I found the powershell code online below and it works fine with replacing letters with other letters but fails when trying to replace the $ special character
get-childitem -recurse | rename-item -newname { $_.name -replace "",""}
I tried using the code below and it ends up adding an s to the end of the file type instead of replacing the $
get-childitem -recurse | rename-item -newname { $_.name -replace "$","s"}
$hortvid.mp4 becomes $hortvid.mp4s instead of shortvid.mp4
Any ideas on how to get this to work correctly?
Just use \ escape character:
When running line in the directory:
get-childitem -recurse | rename-item -newname { $_.name -replace "\$","s"}
input file:
$hortvid.mp4
output file is renamed:
shortvid.mp4
$ is used for specify variable in powershell. And a string with double quote is evaluate in powershell like this :
$variable1="Hello"
$variable2="$variable1 world"
$variable2
if you dont want evaluate a character into a double quote string, you can backslash you caractere like the proposed solution of #lww. Or simply, you can use simple quote.
Like this :
Get-ChildItem -recurse | Rename-Item -Newname { $_.Name -replace '$', 's'}
I'm trying to update a group of XML based .config files. There is a string in the file that contains a plus sign that I cannot replace with my script:
< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= />
If I include the plus sign, the script does nothing. Since all the configs vary I need to replace the text - cannot just go with new files.
The desired result is that the matching value in the file be replaced with the specified value, but the + symbol is not allowing this. Here is my PS script:
$DIRs = Get-ChildItem -Path "C:\TEST" -Directory
Get-ChildItem $DIRs -File -Recurse -Filter *.config |
ForEach { (Get-Content $_.FullName) |
ForEach { $_ -replace '< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= />','< SharedPassKey=123456789abcdefghi/JKLM.nopqrst= />' } |
Set-Content $_.FullName }
As a test I replaced all the text up to the plus sign and it worked fine, but the plus sign and following were present at the end of the new text as I had left the "+nopqrst" out of the script.
Running on PSv3, FYI.
The -replace operator uses a regular expression for the first postfix argument to define the search pattern. In a regular expression, certain characters have a special meaning. + in particular is a so-called "quantifier" with the meaning "one or more times the preceding (sub)expression". In order to replace literal special characters, you need to escape them.
Fortunately, there's a built-in method for escaping strings:
$_ -replace [RegEx]::Escape('< SharedPassKey=123456789abcdefghi/JKLM+nopqrst= />'),'< SharedPassKey=123456789abcdefghi/JKLM.nopqrst= />'
If you have valid XML data and you want to modify the value of a node attribute in an XML file you may want to consider using a proper XML parser, like this:
$xmlfile = 'C:\path\to\your.config'
[xml]$xml = Get-Content $xmlfile
$attr = $xml.SelectSingleNode('//somenode/#SharedPassKey')
$attr.'#text' = $attr.'#text'.Replace('+', '.')
$xml.Save($xmlfile)
Make the XPath expression for selecting the attribute as specific as it needs to be. That will allow you to replace a + with a . in just that attribute.
How to write script in powershell which finds given string in all files in given directory and changes it to given second one ?
thanks for any help,
bye
Maybe something like this
$files = Get-ChildItem "DirectoryContainingFiles"
foreach ($file in $files)
{
$content = Get-Content -path $file.fullname
$content | foreach {$_ -replace "toreplace", "replacewith"} |
Set-Content $file.fullname
}
If the string to replace spans multiple lines then using Get-Content isn't going to cut it unless you stitch together the output of Get-Content into a single string. It's easier to use [io.file]::ReadAllText() in this case e.g.:
Get-ChildItem | Where {!$_.PSIsContainer} |
Foreach { $txt = [IO.File]::ReadAllText($_.fullname);
$txt -replace $old,$new; $txt | Out-File $_}
Note with with $old, you may need to use a regex directive like '(?s)' at the beginning to indicate that . matches newline characters also.
I believe that you can get the list of all files in a directory (simple?). Now comes the replacement part. Here is how you can do it with power shell:
type somefile.txt | %{$_ -replace "string_to_be_replaces","new_strings"}
Modify it as per your need. You can also redirect the output to a new file the same way you do other redirection (using: >).
To get the list of files, use:
Get-ChildItem <DIR_PATH> -name