Windows batch command to ignore some file lines? - windows

I am redirecting the output of a cvs diff onto a log.txt file.
C:\Temp> cvs diff -b -B -r 1.5 -r 1.6 Project\src\Sample.java > log.txt
The generated content of the log.txt file upon executing the above command is like this :
Index: project/src/Sample.java
===================================================================
RCS file: \repobase/src/Sample.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -r1.5 -r1.6
78a79,82
> public java.lang.Class getJavaClass() {
> return Sample.class;
> }
>
92c96
< return Demo.getparentClass(this.getClass());
---
> return MyClass.clazz;
All lines of this file that start with < or > are not necessary. I want to ignore all such lines only to push in the minimal rest into the log.txt file. How can I do this via windows command line?

Perhaps the cvs diff --brief option will give you what you want.
If not, then you can pipe the diff output to FINDSDTR and let it filter the lines
cvs diff -b -B -r 1.5 -r 1.6 Project\src\Sample.java | findstr /vbl "< >" > log.txt
/v option means print lines that don't contain any of the strings
/b option means match the search string starting at the beginning of each line
/l means literal search string (as opposed to a regular expression)
Search string is split at each space, so "< >" is really 2 search strings.
For more more help on FINDSTR use `FINDSTR /?'.
For additional help see What are the undocumented features and limitations of the Windows FINDSTR command?

Related

Script that lists all file names in a folder, along with some text after each name, into a txt file

I need to create a file that lists all the files in a folder into a text file, along with a comma and the number 15 after. For example
My folder has video.mp4, video2.mp4, picture1.jpg, picture2.jpg, picture3.png
I need the text file to read as follows:
video.mp4,15
video2.mp4,15
picture1.jpg,15
picture2.jpg,15
picture3.png,15
No spaces, just filename.ext,15 on each line. I am using a raspberry pi. I am aware that the command ls > filename.txt would put all the file names into a folder, but how would I get a ,15 after every line?
Thanks
bash one-liner:
for f in *; do echo "$f,15" >> filename.txt; done
To avoid opening the output file on each iteration you may redirect the entire output with > filename.txt:
for f in *; do echo "$f,15"; done > filename.txt
$ printf '%s,15\n' *
picture1.jpg,15
picture2.jpg,15
picture3.png,15
video.mp4,15
video2.mp4,15
This will work if those are the only files in the directory. The format specifier %s,15\n will be applied to each of printf's arguments (the names in the current directory) and they will be outputted with ,15 appended (and a newline).
If there are other files, then the following would work too, regardless of whether there are files called like this or not:
$ printf '%s,15\n' video.mp4 video2.mp4 picture1.jpg picture2.jpg "whatever this is"
video.mp4,15
video2.mp4,15
picture1.jpg,15
picture2.jpg,15
whatever this is,15
Or, on all MP4, PNG and JPEG files:
$ printf '%s,15\n' *.mp4 *.jpg *.png
video.mp4,15
video2.mp4,15
picture1.jpg,15
picture2.jpg,15
picture3.png,15
Then redirect this to a file with printf ...as above... >output.txt.
If you're using Bash, then this will not make use of any external utility, as printf is built into the shell.
You need to do something like this:
#!/bin/bash
for i in $(ls folder_name); do
echo $i",15" >> filename.txt;
done
It's possible to do this in one line, however, if you want to create a script, consider code readability in the long run.
Edit 1: better solution
As #CristianRamon-Cortes suggested in the comments below, you should not rely on the output of ls because of the problems explained in this discussion: why not parse ls. As such, here's how you should write the script instead:
#!/bin/bash
cd folder_name
for i in *; do
echo $i",15" >> filename.txt;
done
You can skip the part cd folder_name if you are already in the folder.
Edit 2: Enhanced solution:
As suggested by #kusalananda, you'd better do the redirection after done to avoid opening the file in each iteration of the for loop, so the script will look like this:
#!/bin/bash
cd folder_name
for i in *; do
echo $i",15";
done > filename.txt
Just 1 command line using 2 msr commands recusively (-r) search specific files:
msr -rp your-dir1,dir2,dirN -l -f "\.(mp4|jpg|png)$" -PAC | msr -t .+ -o '$0,15' -PIC > save-file.txt
If you want to sort by time, add --wt to first command like: msr --wt -l -rp your-dirs
Sort by size? Add --sz but only the prior one is effective if use both --sz and --wt.
If you want to exclude some directory, add like: --nd "^(test|garbage)$"
remove tail \r\n in save-file.txt : msr -p save-file.txt -S -t "\s+$" -o "" -R
See msr.exe / msr.gcc48 etc in my open project https://github.com/qualiu/msr tools directory.
A solution without a loop:
ls | xargs -i echo {},15 > filename.txt

Grep for windows

Old.txt contains
apple
orange
banana
And New.txt contains
apple
orange
banana
grape
lemon
I can access new contents which are added to New.txt using grep command.
grep -Fxvf Old.txt New.txt > difference.txt
Now, difference.txt contains
grape
lemon
In Windows, I have tried
findstr /rvc:Old.txt New.txt > difference.txt
to find the difference but it append contents of Old.txt too. How can I write equivalent command in Windows?
You can use DOS findstr with the following flags:-
/v : Prints only lines that do not contain a match.
/g: file : Gets search strings from the specified file.
The command would be something like:-
C:\Users\dude\Desktop>findstr /v /g:Old.txt New.txt >difference.txt
Now checking the file output using the type command; equivalent to cat in Linux, we see :-
C:\Users\dude\Desktop>type difference.txt
grape
lemon
Unless you are restricted from installing anything on your PC, considering installing ports of *nix-like tools such as GnuWin32 and continue to use grep.

shell program to modify contents of a file

I have a file that has a list of product ids each on one line. I want to modify this file in a way that all product ids are on one line and comma separated and in inverted commas. Original format -
1\n2\n3\n
Expected format -
'1','2','3'
I tried the following command -
paste -s -d "','" velocities.txt > out.txt
The result is looking like this -
1',2'3'4,
I do understand that using the above command I wont get the anything before the first product id, but i will be able to handle that case.
You could use sed to quote all digits:
paste -s -d, velocities.txt | sed "s|\([0-9]\+\)|'\1'|g" > out.txt
P.S. Another command that also handles IP-addressed:
sed "s|^\(.*\)$|'\1'|g" velocities.txt | paste -s -d, - > out.txt

Return previous line with Findstr

I am running FINDSTR command to find specific text in .txt files. I want to print matching lines as well as 1 previous line.
findstr "ActualStartDate:" * > a.txt
if my file is like this
abcd
defg
cds
ActualStartDate: invalid date
Result should be like this
cds
ActualStartDate: invalid date
try this with grep for Windows:
grep -1 "ActualStartDate:" *.txt
output is eg.:
file.txt-cds
file.txt:ActualStartDate: invalid date
There is a tool written as a batch file that can do this easily, which uses built in Windows scripting.
findrepl.bat - http://www.dostips.com/forum/viewtopic.php?f=3&t=4697

Concatenate text files with Windows command line, dropping leading lines

I need to concatenate some relatively large text files, and would prefer to do this via the command line. Unfortunately I only have Windows, and cannot install new software.
type file1.txt file2.txt > out.txt
allows me to almost get what I want, but I don't want the 1st line of file2.txt to be included in out.txt.
I have noticed that more has the +n option to specify a starting line, but I haven't managed to combine these to get the result I want. I'm aware that this may not be possible in Windows, and I can always edit out.txt by hand to get rid of the line, but is there a simple way of doing it from the command line?
more +2 file2.txt > temp
type temp file1.txt > out.txt
or you can use copy. See copy /? for more.
copy /b temp+file1.txt out.txt
I use this, and it works well for me:
TYPE \\Server\Share\Folder\*.csv >> C:\Folder\ConcatenatedFile.csv
Of course, before every run, you have to DELETE C:\Folder\ConcatenatedFile.csv
The only issue is that if all files have headers, then it will be repeated in all files.
I don't have enough reputation points to comment on the recommendation to use *.csv >> ConcatenatedFile.csv, but I can add a warning:
If you create ConcatenatedFile.csv file in the same directory that you are using for concatenation it will be added to itself.
Use the FOR command to echo a file line by line, and with the 'skip' option to miss a number of starting lines...
FOR /F "skip=1" %i in (file2.txt) do #echo %i
You could redirect the output of a batch file, containing something like...
FOR /F %%i in (file1.txt) do #echo %%i
FOR /F "skip=1" %%i in (file2.txt) do #echo %%i
Note the double % when a FOR variable is used within a batch file.
I would put this in a comment to ghostdog74, except my rep is too low, so here goes.
more +2 file2.txt > temp
This code will actually ignore rows 1 and 2 of the file. OP wants to keep all rows from the first file (to maintain the header row), and then exclude the first row (presumably the same header row) on the second file, so to exclude only the header row OP should use more +1.
type temp file1.txt > out.txt
It is unclear what order results from this code. Is temp appended to file1.txt (as desired), or is file1.txt appended to temp (undesired as the header row would be buried in the middle of the resulting file).
In addition, these operations take a REALLY LONG TIME with large files (e.g. 300MB)
Here's how to do this:
(type file1.txt && more +1 file2.txt) > out.txt
In powershell:
Get-Content file1.txt | Out-File out.txt
Get-Content file2.txt | Select-Object -Skip 1 | Out-File -Append out.txt
I know you said that you couldn't install any software, but I'm not sure how tight that restriction is. Anyway, I had the same issue (trying to concatenate two files with presumably the same headers) and I thought I'd provide an alternative answer for others who arrive at this page, since it worked just great for me.
After trying a whole bunch of commands in windows and being severely frustrated, and also trying all sorts of graphical editors that promised to be able to open large files, but then couldn't, I finally got back to my Linux roots and opened my Cygwin prompt. Two commands:
cp file1.csv out.csv
tail -n+2 file2.csv >> out.csv
For file1.csv 800MB and file2.csv 400MB, those two commands took under 5 seconds on my machine. In a Cygwin prompt, no less. I thought Linux commands were supposed to be slow in Cygwin but that approach took far less effort and was way easier than any windows approach I could find.
You can also simply try this
type file2.txt >> file1.txt
It will append the content of file2.txt at the end of file1.txt
If you need original file1.txt, take a backup beforehand. Or you can do this
type file1.txt > out.txt
type file2.txt >> out.txt
If you want to have a line break at the end of the first file, you can try the following command before appending.
type file1.txt > out.txt
printf "\n" >> out.txt
type file2.txt >> out.txt
The help for copy explains that wildcards can be used to concatenate multiple files into one.
For example, to copy all .txt files in the current folder that start with "abc" into a single file named xyz.txt:
copy abc*.txt xyz.txt
more +2 file1.txt > type > out.txt && type file2.txt > out.txt
This takes Test.txt with headers and appends Test1.txt and Test2.txt and writes results to Testresult.txt file after stripping headers from second and third files respectively:
type C:\Test.txt > C:\Testresult.txt && more +1 C:\Test1.txt >> C:\Testresult.txt && more +1 C:\Test2.txt >> C:\Testresult.txt

Resources