Translate a Unix1Liner to PowerShell - powershell

I would like to translate the following Unix 1 Liner to PowerShell.
Synopsis of the command:
This command will search recursively form the PWD (pressent working directory) for any file with the extenstion .jsp, and look inside the file for a simple string match of 'logoutButtonForm'. If it finds a match, it will print the file name and the text that it matched.
find . -name "*.jsp" -exec grep -aH "logoutButtonForm" {}\;
I am new to power shell and have done some googling/binging but have not found a good answer yet.

ls . -r *.jsp | Select-String logoutButtonForm -case
I tend to prefer -Filter over -Include. Guess I never trusted the -Exclude/-Include parameters after observing buggy behavior in PowerShell 1.0. Also, -Filter is significantly faster than using -Include.

Related

Perl: List files and directories recursively but exclude some directories and files that passed

Please give any suggestion or snippet or anything that may work.
I have already tried wanted function but how do I exclude some directory while recursing?
In Linux, you can make use of the Linux "find" and "grep" commands and run those Linux commands in Perl using qx to store Linux command result in Perl.
e.g.
$cmd = "find . | grep -v 'dir1\|dir2\|...\|dirn'";
$result=qx($cmd);
The above command combinations do the following:
The find command will list the all the directory and
files recursively.
The pipe "|" will pass the find result to grep command
The grep -v command will print on screen only the string not exist
in the "dir1", "dir2"..."dirn" to be ignored
At last, the qx command will execute the find and grep Linux
commands and stored the output to $result variable.
You can do the similar thing in Windows. The only difference is to use the Windows command line.
e.g.
$result=qx('dir /b/s | find /v "workspace" | find /v "TVM"')
The above command will list all the directory recursively except the directory has name "workspace" or "TVM".

Compressing to tar.xz using 7-zip through a pipe on windows

My command line is this (powershell):
$7z ="`"c:\Program Files\7-Zip\7z.exe`""
&$7z a -r -ttar -bd -so . | &$7z a -r -txz -bd $archive -si
The produced archive file indeed contains a tar file, but that tar file is corrupt.
Note, that breaking the pipe into two commands works correctly:
&$7z a -r -ttar -bd ${archive}.tmp .
&$7z a -r -txz -bd $archive ${archive}.tmp
The produced archive is perfectly valid.
So, what is wrong with my pipeline?
(I am using Powershell)
Nothing is wrong with your pipeline it is the way that the pipeline works that's causing the error.
PowerShell pipe works in an asynchronous way. Meaning that output of the first command is available to the second command immediately one object at the time even if the first one has not finished executing, See here.
Both Unix and PowerShell pipes operate in the same way. The reason why you might be seeing a difference from Unix to PowerShell is the way in which they go about it is different.
Unix passes Strings between the commands. Where as a Powershell pipe will pass full-fledged .net object between commands. This difference in the data type being past between command will be why it works on unix and not in PowerShell. If 7z.exe can not huddle these .net objects correctly the files will be come corrupt, See here.
Try adding | %{ "$_" } in between the pipes like
&$7z a -r -ttar -bd -so . | %{ "$_" } | &$7z a -r -txz -bd $archive -si
The point is that the second call to 7z expects unmodified data on STDIN, but PowerShell is converting the output from the first call to 7z to (multiple) (string) objects. % is an alias for foreach-object, so what the additional command does is to loop over each object and convert it to a plain string before passing it on to the second call to 7z.
Edit: Reading through PowerShell’s Object Pipeline Corrupts Piped Binary Data it looks to me now as if my suggestion would not work, and there's also no way to fix it. Well, other than wrapping the whole pipeline into a cmd /c "..." call to make cmd and not PowerShell handle the pipeline.
Edit2: I also was trying this solution from the PowerShell Cookbook, but it was very slow.
In the end, I created a .cmd script with the 7z pipes that I'm calling from my PowerShell script.

Recursively replace colons with underscores in Linux

First of all, this is my first post here and I must specify that I'm a total Linux newb.
We have recently bought a QNAP NAS box for the office, on this box we have a large amount of data which was copied off an old Mac XServe machine. A lot of files and folders originally had forward slashes in the name (HFS+ should never have allowed this in the first place), which when copied to the NAS were all replaced with a colon.
I now want to rename all colons to underscores, and have found the following commands in another thread here: pitfalls in renaming files in bash
However, the flavour of Linux that is on this box does not understand the rename command, so I'm having to use mv instead. I have tried using the code below, but this will only work for the files in the current folder, is there a way I can change this to include all subfolders?
for f in *.*; do mv -- "$f" "${f//:/_}"; done
I have found that I can find al the files and folders in question using the find command as follows
Files:
find . -type f -name "*:*"
Folders:
find . -type d -name "*:*"
I have been able to export a list of the results above by using
find . -type f -name "*:*" > files.txt
I tried using the command below but I'm getting an error message from find saying it doesn't understand the exec switch, so is there a way to pipe this all into one command, or could I somehow use the files I exported previously?
find . -depth -name "*:*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//:/_}"' _ {} \;
Thank you!
Vincent
So your for loop code works, but only in the current dir. Also, you are able to use find to build a file with all the files with : in the filename.
So, as you've already done all this, I would just loop over each line of your file, and perform the same mv command.
Something like this:
for f in `cat files.txt`; do mv $f "${f//:/_}"; done
EDIT:
As pointed out by tripleee, using a while loop is a better solution
EG
while read -r f; do mv "$f" "${f//:/_}"; done <files.txt
Hope this helps.
Will

Batch processing Pandoc conversions in Windows

I am trying to convert a large number of HTML files into Markdown using Pandoc in Windows, and have found an answer on how to do this on a Mac, but receive errors when attempting to run the following in Windows PowerShell.
find . -name \*.md -type f -exec pandoc -o {}.txt {} \;
Can someone help me translate this to work in Windows?
to convert files in folders recursively try this (Windows prompt command line):
for /r "startfolder" %i in (*.htm *.html) do pandoc -f html -t markdown "%~fi" -o "%~dpni.txt"
For use in a batch file double the %.
Most of the answers here (for ... solutions) are for cmd.exe, not PowerShell.
mb21's answer is on the right track, but has a bug with respect to targeting each input file; also, it is hard to parse visually.
The functionally equivalent PowerShell command is:
Get-ChildItem -File -Recurse -Filter *.md | ForEach-Object {
pandoc -o ($_.FullName + '.txt') $_.FullName
}
Endoro's answer is great, don't get confused by the parameters added to %i.
For helping others, I needed to convert from RST (restructured text) to dokuwiki syntax, so I created a convert.bat with:
FOR /r "startfolder" %%i IN (*.rst) DO pandoc -f rst -t dokuwiki "%%~fi" -o "%%~dpni.txt"
Works for all rst files in folders and subfolders.
If you want to go recursively through a directory and its subdirectories to compile all the files of type, say, *.md, then you can use the batch file I wrote in answer to another question How can I use pandoc for all files in the folder in Windows? . I call it pancompile.bat and the usage is below. Go to the other answer for the code.
Usage: pancompile DIRECTORY FILENAME [filemask] ["options"]
Uses pandoc to compile all documents in specified directory and subdirectories to a single output document
DIRECTORY the directory/folder to parse recursively (passed to pandoc -s);
use quotation marks if there are spaces in the directory name
FILENAME the output file (passed to pandoc -o); use quotation marks if spaces
filemask an optional file mask/filter, e.g. *.md; leave blank for all files
"options" optional list of pandoc commands (must be in quotation marks)
Minimal example: pancompile docs complete_book.docx
Typical example: pancompile "My Documents" "Complete Book.docx" *.md "-f markdown -t docx --standalone --toc"
Using the powershell built-in gci:
gci -r -i *.md |foreach{$docx=$_.directoryname+"\"+$_.basename+".docx";pandoc $_.name -o $docx}
from https://github.com/jgm/pandoc/issues/5429
I created a python script that I've been using to convert a tree of markdown files into a single output file. It's available on github:
https://github.com/andrewrproper/pandoc-folder

using grep and find commands - basic questions to help me sort it out in my simple mind

I am back with a second no-brainer question, but I would like to get this straight in my head.
I have an assignment in which I am charged with providing a command to find a file named test in my home directory (one command using find, and one using grep). I understand that using find is just 'find ~/test', but using grep, wouldn't I have to search out a pattern within the file 'test'? Or is there a way to search for the file (using grep), even if the file is empty?
ls ~ | grep test
I understand that using find is just 'find ~/test'
No. find ~/test will also have a match for every file or directory under the directory $HOME/test/. Rather use find ~ -type f -name test.
The assignment sounds unclear. But yes, if you give any filenames to grep, it will look at the contents of the files and ignore the names of the files. Perhaps you can grep the output of another command? Maybe ls as #Reese suggested, or maybe a different find command.
ls -R ~ | grep test
Explanation: ls -R ~ will recursively list all files and directories in your home folder. grep test will narrow down that list to files (and directories) that have "test" in their name.