cmd: replace inner part of a filename (using regular expression mask) [closed] - regex

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
I run a small batch-file to rename some txt-file:
"C:\backup\t1-dd-dd t2-dd-dd.txt"
in the filename d - is a digit (from 0 to 9);
note: there is space in the filename between t1 and t2 marks (I need it for some reason).
now, I need to replace digits only in the 't1-dd-dd' part of the filename.
with powershell Rename-Item it can be done like this (example):
powershell -command "& { Get-ChildItem с:\backup -filter 't1-* t2-*.txt' | Rename-Item -NewName { $_.Name -replace 't1-\d\d-\d\d','t1-00-99' } }"
result would be like this:
C:\backup\t1-14-26 t2-56-48.txt (old filename)
C:\backup\t1-00-99 t2-56-48.txt (new filename)
is it possible to do same thing without powershell, just using cmd RENAME command?

You can't do it with regex, but you can do it with RENAME wildcards.
ren "c:\backup\t1-??-?? t2-??-??.txt" "???00-99*"
Within the target mask, each ? preserves one character, and the literals do a one for one character replacement, and the * preserves the remainder.
See How does the Windows RENAME command interpret wildcards? for more info.
If you are worried that the source mask is not specific enough, then you could use the following batch script to guarantee only properly named files are renamed.
pushd "c:\backup"
for /f "delims=" %%F in (
'dir /b /a-d "t1-??-?? t2-??-??.txt" ^| findstr /xirc:"t1-[0-9][0-9]-[0-9][0-9] t2-[0-9][0-9]-[0-9][0-9].txt"'
) do ren "%%F" "???00-99*"
popd
But your powershell script is probably easier :-)

Related

How to better troubleshoot/debug Powershell [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
EDIT
My Regex was off, though, I'm having the same issue stull
https://regex101.com/r/wUHyZm/4
I was able to paste in a huge amount of input and got 50 matches using the link above, but still can't get powershell to flag a match.
Please see the below link for my regex and sample input
https://regex101.com/r/wUHyZm/4
https://regex101.com/r/wUHyZm/2
Basically I have a folder with a bunch of sub folders.
My script parses through each subfolder looking for "results.nmap".
It then opens the file (a text file) and I am intending for it to extract data that meets certain requirements.
Get-ChildItem -LiteralPath "U:\nmap reports\Nmap Subnet Scans\August2019" -Filter *.nmap -File -Recurse | foreach {
$currentfolder = $_.Directory
$RegX = [RegEx]'(?m)^Nmap scan report for\s+(?<Device>.+)\r?\n(?:.+\r?\n){3,6}23\/tcp\s+open\s+telnet$'
$content = Get-Content -Path "$currentfolder\results.nmap" -Raw
if ($content -match $RegX) {
Write-Host 'issa match'
}
#write-host $content
#[regex]::Matches($content,$RegX).ForEach({ $_.Groups['Device'].Value })
}
I can't seem to get it to match in powershell, but it matches in the link above.
I also don't get any errors
I had a previous question regarding the regex side, and a kind user provided:
[regex]::Matches($content,$RegX').ForEach({ $_.Groups['Device'].Value })
Which doesn't yield results either, though logically I don't see why it wouldn't.
Write-Host $content
Looks exactly like it should in my provided link above.
I'm not looking for an answer, moreso I'm looking for a good way to troubleshoot this so I can better teach myself
In the ISE, you can use the debugger to step or set breakpoints, and run any arbitrary powershell command at the debug prompt, and mouse over variables to see their current value.
You can change the value of a variable and continue running. Even write a new function.

unix change number's value on given line number in shell script for loop [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How can I change a number on a line in a file using a unix tool like awk or sed?
I want to change the line 3 in my example file to the number 1-10 using a shell script. I think I need to use regex to recognize the digit but I'm not sure how to do this, or to allow multiple digits (like 10).
Example file:
/examples/are/hard so/hard/1
Shell script so far:
for i in {1..3};
do
sed 's|/examples/are/hard so/hard/7 | /examples/are/hard so/hard/'"$i" ex_file
cat ex_file
done
Desired output:
/examples/are/hard so/hard/1
/examples/are/hard so/hard/2
/examples/are/hard so/hard/3
What you've run isn't a valid sed command. If you're trying to do a substitution, that's s/search/replace/flags.
I imagine you meant:
sed 's/here\/is the number\/to\/change 3/here\/is the number\/to\/change '"$i"'/' ex_file
Note that we temporarily break out of single quote. Inside of single quotes, variable aren't interpolated. We swap the double quotes, bring in $i, then return to single quotes to finish the command.
P.S. You also don't have to use / as your delimiter.
sed 's|here/is the number/to/change 3|here/is the number/to/change '"$i"'|' ex_file

Windows Batch - check if string starts with ... in a loop

this grabs the output from a remote branch list with git::
for /f "delims=\" %r in ('git branch -r') do (
::then in here I want to get rid of the origin/HEAD -> line of the output
::and do a few git ops on the other lines, which are the names of branches
)
anyhow, I'm finding this frustrating as apparently batch doesn't have regex
here's the code I'm using to do this in bash
for remote in `git branch -r | grep -v '\->'`;
do echo $remote; #...git stuff
done;
the grep removes the "origin/HEAD -> origin/master" line of the output of git branch -r
So I'm hoping to ask how to implement the 'contains' verb
for /f "delims=\" %r in ('git branch -r') do (
if not %r contains HEAD (
::...git stuff
)
)
on a loop variable
this stackoverflow question appears to answer a similar question, although in my attempts to implement as such, I became confused by % symbols and no permutation of them yielded function
EDIT FOR FUTURE READERS: there is some regex with findstr /r piped onto git branch -r
for /f "delims=\" %%r in ('git branch -r^|findstr "HEAD"') do (
echo ...git stuff %%r
)
should give you a start.
Note: %%r, not %r within a batch file - %r would work directly from the prompt.
Your delims=\ filter will produce that portion up to the first \ of any line from git branch -r which contains HEAD - sorry, I don't talk bash-ish; you'd need to say precisely what the HEAD string you want to locate is.
Use "delims=" fo the entire line - omitting the delims option will set delimiters to the default set (space, comma, semicolon, etc.)
Don't use ::-comments within a block (parenthesised statement-sequence) as it's actually a broken label and cmd doesn't appeciate labels within a block. Use REM comments here instead.
The resultant strings output from the findstr (which acts on a brain-dead verion of regex) will be processed through to the echo (or whatever statement you may substitute here) - if there are none, the for will appear to be skipped.
Quite what your target string would be for findstr I can't tell. From the prompt, findstr /? may reveal. You may also be able to use find (find /?) - but if you are using cygwin the *nix version of find overrides windows-native.
I don't know what the git branch output looks like, but with a test case of
test 1
HEAD test \-> 2
test 3
test 4
the following prints all the text lines except the one containing \->
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "tokens=*" %%r in (d:\test2.txt) do (
set str1=%%r
if "!str1:\->=!"=="!str1!" (
echo %%r
)
)
The if test is fundamentally doing this test: string1.replace("HEAD", "") == string1.
Your loop variable needs to be %r if used directly in the command prompt, but %%r if in a batch file.
The string replacement is a part of environment variables, not loop variables, so it needs to be put into a holding string (str1) to work with. If you have the command extensions enabled ( enableextensions ).
And because environment variable setting operations happen when the script is read, you need to override that with enabledelayedexpansion and using !str1! instead of %str1%, otherwise the value of str1 won't change from one loop to the next.
(PS. Use PowerShell instead. Get-Content D:\test2.txt | Select-String "\->" -NotMatch ).

Move files starting with number and of type pdf [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am just a beginner in regex, so please forgive me if this question is too easy.
What I want to ask is that I have a bunch of files in a directory and I move some of the files which start with numbers and of type pdf. How to use regex with mv command and what would be the regex.
If you're using linux command prompt, actually you're not using Regex, but you're using GLOB notation instead, which is different. Read up on that. GLOB cannot take complex pattern such as the one you describe. You need to use real regex.
For your case, you can use grep command on the output of ls to find the files meeting your requirement, then call mv on them. Something like this:
while read fileName; do mv $fileName destination_folder; done < <(ls -1 | grep -E '[0-9].*\.pdf')
Let's break it up:
while read fileName; do
mv $fileName destination_folder;
done < <(ls -1 | grep -E '[0-9].*\.pdf')
So basically you read through the directory listing using while loop, which gets the input from the output of the last line ls -1 | grep -E '[0-9].*\.pdf'. Using while loop (instead of simpler for loop) is necessary to cater filenames containing spaces.
Now the command ls -1 | grep -E '[0-9].*\.pdf' basically just list down the filenames, and grab only those matching specified RegEx pattern.
You could use find too:
find . -maxdepth 1 -name "[0-9]*.pdf" -exec mv {} destination \;

Add and Sort numbers in files [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have directories like
./2012/NY/F/
./2012/NJ/M/
....
Under these directories, there are files with names like Zoe etc...
Each file contains a number.
I'd like to sum the numbers in the file with same file name in different directories and find the max of sum, how should I write?
To locate the files, use a glob such as specified in this question.
To do the actual summing, there are quite a few possibilities depending on the number of files and range of the numbers, but a reasonably general-purpose way would be with awk:
awk '{sum += $1} END { print sum }' file1 file2 ...
Suppose that your ./2012/NY/F, /2012/sfs/XXS all under directory, say, /home/yourusername/data/,
You can try this if you are using *nix or if you have cygwin installed on your windows
cd /home/yourusername/data ; find ./ -name yourfile_name_to_lookup.txt | xargs awk 'BEGIN {sum=0} ; {sum+=$1} ; END {print sum} '
I assume the number starting from the first column in that file ($1).
If you know the unique names of the files and the file names don't have space in them, then following may work.
cd 2012/
for i in "Zoe" "file2" "file3"
do
k=$(cat $(find . -type f -name "$i"));
echo $k | awk '{for(i=t=0;i<NF;) t+=$++i; $0=t}1';
done | sort -r
This will sum up files with same names from subdirs under 2012 and sort -r will return the numbers in max to min order.
I assume that the entire contents of the file is a number. I assume that the number is an integer. Requires bash 4 for the associative array
declare -A sum_for_file
for path in ./2012/*/*/*; do
(( sum_for_file["$(basename "$path")"] += $(< "$path") ))
done
max=0
for file in "${!sum_for_file[#]}"; do
if (( ${sum_for_file["$file"]} > max )); then
max=${sum_for_file["$file"]}
maxfile=$file
fi
# you didn't say you needed to print it, but if you do
printf "%d\t%s\n" ${sum_for_file["$file"]} "$file"
done
echo "the maximum sum is $max found in files named $maxfile"