Findstr does not return second line - windows

I am using FINDSTR -I to find a string in n number of files in a folder. Also write the results to a new file.
I need find string "IDC" along with number next to it in all files.
but on some lines in files, IDC is spread across two lines, and my search returns just first line.
09:49:34.386 4;**IDC-200.0**;CA
13:07:39.987 87;T22.8,BT2;LI;VLT12.7;**IDC-**
13:07:39.995 **42.0**;CAP240.0/
can some one help in copy next line to output file, if IDC is spread across two lines.

Microsoft’s findstr works strictly line based. It is not really possible to search for a string which does not completely exist within a line and get all lines output.
But it is possible to define multiple search strings which are used one after the other on a line before processing next line until either one of the search strings returns a positive match or none of the search strings matches a string on current line.
Example:
%SystemRoot%\System32\findstr.exe /R /C:"IDC-" /C:"^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9][0-9] \*\*[0-9][0-9.]*\*\*;" *.txt
Findstr (SS64 article) searches with those options in all *.txt files of current folder for
a line containing case sensitive the string IDC- anywhere within the line or
a line starting with time in expected format, a space, two asterisks, a floating point number with at least 1 digit before decimal point, two more asterisks and a semicolon.
With those two search strings all 3 lines of provided example are found and output in correct order and other lines not containing IDC- or matching the second regular expression search string are ignored by FINDSTR.
Note: SS64 article FINDSTR - Searching across Line Breaks explains how a search can be done which includes a line break. But output is nevertheless only the first line on which the found multi-line string begins.

Related

Glob string pattern for one or more files

I need a pattern for one or more files, name of each will be known before the matching occurs (but I do not know what they are right now).
For example, one occurence could be two files: A.lkml and B.lkml, and another could be three: CDFDFDSADF.lkml, SD.lkml and R4545452.lkml. The filenames will be passed as a single argument with single space as separator (So for example 1, will see A.lkml B.lkml).
What I can be sure of:
all files end with .lkml
for each matching, I need to add a manifest.lkml into the list. For example, in example 1, the list should contain 3 instead of 2 filenames, A.lkml, B.lkml and manifest.lkml
What puzzles me is that glob pattern matching doesn't seem to be able to do logic "OR". I have tried to use ",", "|" to no avail. In my experiments I fixed the filenames but in reality they change each time.
Update: I think brace expression such as {a.lkml,manifest.lkml} should work. Somehow it doesn't pass.

Extract each occurrence of a string into a separate line to build a list of URLs

I would like to extract all occurrences of a URL string pattern (which can appear multiple times in a file) to build a list of all occurrences.
Currently I can identify each occurrence with the Find in files feature, but I would like the Extract feature to list each occurrence on a new line. Currently the feature lists each line that contains the string. And a line can contain the sting multiple times.
My goal is to get a list of the full URL that contains __data/assets/
In the below example __data/assets/ occurs 48 times.
However, the extract only 44 lines are extracted, but I need to output all 48 occurrences (the full URL).
I will be running this extract over 270 files in total.
View source of this example webpage:
https://www.walkerville.sa.gov.au/council/strategic-plans/2020-2024-living-in-the-town-of-walkerville-a-strategic-community-plan
It looks that all URLs are surrounded by double quotation marks.
If so, you can search for a regular expression:
[^\"]*__data/assets/[^\"]*
and select Display Matched Strings Only in the Extract Options dialog box.

Oracle - regexp_replace to check beginning of each line in a string consisting of many lines

I have a random string consisting of many lines and different number of characters in each line. I need to convert this string such that I have a fixed number of characters ,say 10, in each line. Also each of my new lines shouldn't start with a :
I tried :
l_str:=replace(l_str,chr(10),''); -- To first create a single long string
:
I wrote the logic to divide the new long string to lines of 10 characters.
Now each line I used the
l_str:=regexp_replace(l_str,'^:','/');
And then I concatenated all the lines.
Can I first concatenate my entire string to one and then use the regexp_replace?
Will it be possible to check the start of each line using regexp_replace itself?
Yes, if you set match_parameter to 'm' (for multiline). More info is in the documentation about REGEXP_LIKE.
See f.i. here or here.

Find files NOT matching *_abc.*

In dos, when I wanted to get a list of files matching a specific filter, I could use something along the lines of:
*.* - Means return everything
*.txt - Means return all files with a .txt extension
*_abc.* - Means return every file that ends with _abc
My question is, using that dos filter structure, how could I return all files NOT matching *_abc.* (In other words, return all files whos name does NOT end in _abc)?
I don't remember if this is possible and I need this since a company I'm working with is using a very old program that still uses that form of command filtering for selecting files for the program to work on - Also, unfortunately, I can't do it via a batch command... It has to be a single command line statement.
Thanks!!!
Pipe the results of your listing to FINDSTR with an appropriate regex search string and the /V option to filter out matching lines.
dir /b /a-d * | findstr /v /r "_abc\.[^.]*$"
Take a look at this answer to a sort of unrelated question. The answer does show though how to do a REGEX search on file names, and of course if you use a REGEX you can easily search for things that don't match the expression.
https://stackoverflow.com/a/7381962/1246574
Hope that helps.
EDIT
Sorry, didn't see you needed it to be a single line statement and not a batch. I'll leave the above answer though in case it helps anyone else, and I'll also see if I can look up how to do it in a single statement.

Using sed to modify line not containing string

I am trying to write a bash script that uses sed to modify lines in a config file not containing a specific string. To illustrate by example, I could have ...
/some/file/path1 ipAddress1/subnetMask(rw,sync,no_root_squash)
/some/file/path2 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1)
/some/file/path3 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=0)
/some/file/path4 ipAddress2/subnetMask(rw,sync,no_root_squash,anongid=-1)
/some/file/path5 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
And I want every line's parenthetical list to be changed such that it contains strings anonuid=-1 and anongid=-1 within its parentheses ...
/some/file/path1 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path2 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path3 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path4 ipAddress2/subnetMask(rw,sync,no_root_squash,anongid=-1,anonuid=-1)
/some/file/path5 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
As can be seen from the example, both anonuid and anongid may already exist within the parentheses, but it is possible that the original parenthetical list has one string but not the other (lines 2, 3, and 4), the list has neither (line 1), the list has both already set properly (line 5), or even one or both of them are set incorrectly (line 3). When either anonuid or anongid is set to a value other than -1, it must be changed to the proper value of -1 (line 3).
What would be the best way to edit my config file using sed such that anonuid=-1 and anongid=-1 is contained in each line's parenthetical list, separated by a comma delimiter of course?
I think this does what you want:
sed -e '/anonuid/{s/anonuid=[-0-9]*/anonuid=-1/;b gid;};s/)$/,anonuid=-1)/;:gid;/anongid/{s/anongid=[-0-9]*/anongid=-1/;b;};s/)$/,anongid=-1)/'
Basically, it has two nearly identical parts with the first dealing with anonuid and the second anongid, each with a bit of logic to decide if it needs to replace or add the appropriate values. (It doesn't bother to check if the value is already correct, that would just complicate things while not changing the results.)
You can use sed to specify the lines you are interested in:
$ sed '/anonuid=..*,anongid=..*)$/!p' $file
The above will print (p) all lines that don't match the regular expression between the two slashes. I negated the expression by using the !. This way, you're not matching lines with both anaonuid and anongid in them.
Now, you can work on the non-matching lines and editing those with the sed s command:
$ sed '/anonuid=..*,anongid=..*)$/!s/from/to/`
The manipulation might be fairly complex, and you might be passing multiple sed commands to get everything just right.
However, if the string no_root_squash appear in each line you want to change, why not take the simple way out:
$ sed 's/no_root_squash.*$/no_root_squash,anonuid=-1,anongid=-1)/' $file
This is looking for that no_root_squash string, and replacing everything from that string to the end of the line with the text you want. Are there lines you are touching that don't need to be edited? Yes, but you're not really changing those lines. You're basically substituting /no_root_squash,anonuid=-1,anongid=-1) with the same /no_root_squash,anonuid=-1,anongid=-1).
This may be faster even though it's replacing text that doesn't need replacing because there's less processing going on. Plus, it's easier to understand and support in the future.
Response
Thanks David! Yeah I was considering going that route, but I didn't want to rely 100% on every line containing no_root_squash. My current config file only ends in that string, but I'm just not 100% sure that won't potentially be different in the field. Do you think there would be a way to change that so it just overwrites from the end of the last string not containing anonuid=-1 or anongid=-1 onward?
What can you guarantee will be in each line?
You might be able to do a capture group:
sed 's/\(sync,[^,)]*\).*/\1,anonuid=-1,anongid=-1)/' $file
The \(..\) is a capture group. It basically captures that portion of the matching regular expression, and then allows you to reuse it via the \1. I'm capturing from the word sync to a group of characters not including a comma or a closing parentheses. Then, I'm appending the capture group, a comma, and your anon uid and gid.
Will that work?
Maybe I am oversimplifying:
sed 's/anonuid=[-0-9]*[^)]//g;s/anongid=[-0-9]*[^)]//g;s/[)]/anonuid=-1,anongid=-1)/g' test.txt > test3.txt
This just drops any current instance of anonuid or anongid and adds the string
"anonuid=-1,anongid=-1" into the parentheses

Resources