Hey all I found the following code HERE and was wondering if it's possible if I can also get the line number where the word appears by using the LINQ query or by some other means?
Dim startFolder = "C:\Users\me\Documents\Visual Studio 2012\Projects\project"
Dim fileList = New System.IO.DirectoryInfo(startFolder).GetFiles("*.vb", System.IO.SearchOption.AllDirectories)
Dim queryMatchingFiles = From file In fileList _
Where file.Extension = ".vb" _
Let fileText = GetFileText(file.FullName) _
Where fileText.Contains(word2Search) _
Select file.FullName
Debug.Print("The term " & word2Search & " was found in:")
For Each filename In queryMatchingFiles
Debug.Print(filename)
Next
The code works for finding the word but I would really like to be able to know what line it was found on as well.
Any help would be great!
The LINQ Select method has a overload that passes in the index of the item.
Dim startFolder = "C:\Users\me\Documents\Visual Studio 2012\Projects\project"
Dim matches =
From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
Where l.Line.Contains(word2Search)
Select FileName = f, LineNo = l.LineNo, Line = l.Line
Matches will be an IEnumerable of objects with FileName, LineNo and Line properties.
UPDATE
To get the file name and an array of the matching line indexes, you could do something like this:
Dim matches =
From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
Where l.Line.Contains(word2Search)
Select File = f, LineNo = l.LineNo
Group By File Into g = Group
Select FileName = File, LineNos = g.Select(Function(x) x.LineNo).ToArray()
This will give you an IEnumerable of objects with FileName and LineNos properties.
Finding the positions of the matches in the lines requires a few more changes, since Contains just returns a Boolean. You can use Regex.Matches to find the positions of matches in the line, so:
Dim matches =
From f In Directory.EnumerateFiles(startFolder, "*.vb", SearchOption.AllDirectories)
From l In File.ReadLines(f).Select(Function(x, i) New With { .Line = x, .LineNo = i + 1})
Where l.Line.Contains(word2Search)
Select File = f, LineNo = l.LineNo,
MatchPositions = Regex.Matches(l.Line, Regex.Escape(word2Search)).Cast(Of Match)().Select(Function(x) x.Index)
Group By File Into g = Group
Select FileName = File, Matched = g.Select(Function(x) New With { x.LineNo, .Positions = x.MatchPositions.ToArray() }).ToArray()
After this, you end up with an IEnumerable of objects with FileName and Matched properties (unfortunately, VB.NET didn't like that being called Matches because that clashes with the matches variable, but you can play with that to your liking). The Matched property is an array of objects with LineNo and Positions properties, with Positions being an array of the indexes into the strings (zero based, so add a + 1 in there if you like).
Related
Private Async Function cmdList() As Task
Dim m = Context.Message
Dim u = Context.User
Dim g = Context.Guild
Dim c = Context.Client
Dim words As String = ""
Dim embed As New EmbedBuilder With {
.Title = $"Wallpaper keyword list",
.ImageUrl = "https://i.imgur.com/vc241Ku.jpeg",
.Description = "The full list of keywords in our random wallpaper list",
.Color = New Color(masterClass.randomEmbedColor),
.ThumbnailUrl = g.IconUrl,
.Timestamp = Context.Message.Timestamp,
.Footer = New EmbedFooterBuilder With {
.Text = "Keyword Data",
.IconUrl = g.IconUrl
}
}
For Each keyword As String In wall.keywords
words = words + keyword + " **|** "
Next
embed.AddField("Full list", words)
Await m.Channel.SendMessageAsync("", False, embed.Build())
End Function
This is my command to get every word from an array and put it on a field. What I want to know is how do I make it so once the field gets full it'll automatically add a new one and continue with the list. This might be a little far-fetched but just don't know how to go about this. Sorry if I can't understand any of the answers. I'm still a little new to coding on Discord.net and well vb in general.
This is a modification of you hastebin code
Dim row As Integer = 0
Dim words As String = String.Empty
For Each keyword As String In wall.keywords
'If appending the keyword to the list of words exceeds 256
'don't append, but instead add the existing words to a field.
If words.Length + keyword.length + 7 > 256 Then
row += 1
embed.AddField($"List #{row}", words) 'Add words to field
'reset words
words = String.Empty
End If
words = words + keyword + " **|** "
Next
'The add condition within the for loop is only entered when we are
'about to exceed to field length. Anything string under the max
'length would exit the loop without being added. Add it here
embed.AddField($"List #{row + 1}", words)
Await m.Channel.SendMessageAsync("", False, embed.Build())
While it does not change any of the logic, you could consider using a StringBuilder
I have a folder with 700+ .jpgs. I also have a Textbox with one filename per line.
I want to check which file does not exist in the folder, but should be there.
This is my code:
Dim Counter As Integer = 0
For Each Line As String In tbFileNames.Lines
Counter = Counter + 1
If (IO.File.Exists(tbFolder.Text & "\" & tbFileNames.Lines(Counter - 1).ToString & ".jpg")) = False Then
tbNotExistingFiles.Text = tbNotExistingFiles.Text & vbNewLine & (tbFileNames.Lines(Counter - 1).ToString)
Else
End If
Next
Problem: I get more than 300 "missing" files, but there should be only 7. When I search for the output filenames, they are in the folder, so the FileExists functions returns false, but it shouldn't.
Where is the problem? Is it the amount of files?
According to this line:
If (IO.File.Exists(tbFolder.Text & "\" & tbFileNames.Lines(Counter - 1).ToString & ".jpg")) = False
Which can be interpreted as:
The tbFolder TextBox contains the directory's path where the images are located.
The tbFileNames TextBox contains the main and complete file names. One file name per line.
Appending the extension & ".jpg" means that the file names in the tbFileNames TextBox are without extensions. And,
You need to get a list of the missing files in that directory and show the result in the tbNotExistingFiles TextBox.
If my interpretation is correct, then you can achieve that using the extension methods like:
Imports System.IO
'...
Dim missingFiles = tbFileNames.Lines.
Select(Function(x) $"{x.ToLower}.jpg").
Except(Directory.GetFiles(tbFolder.Text).
Select(Function(x) Path.GetFileName(x.ToLower)))
tbNotExistingFiles.Text = String.Join(ControlChars.NewLine, missingFiles)
Or by a LINQ query:
Dim missingFiles = From x In tbFileNames.Lines
Where (
Aggregate y In Directory.EnumerateFiles(tbFolder.Text)
Where Path.GetFileName(y).ToLower.Equals($"{x.ToLower}.jpg")
Into Count()
) = 0
Select x
'Alternative to tbNotExistingFiles.Text = ...
tbNotExistingFiles.Lines = missingFiles.ToArray
Note that, there's no need nor use for the File.Exists(..) function in the preceding snippets. Just in case you prefer your approach using For..Loop and File.Exists(..) function, then you can do:
Dim missingFiles As New List(Of String)
For Each line In tbFileNames.Lines
If Not File.Exists(Path.Combine(tbFolder.Text, $"{line}.jpg")) Then
missingFiles.Add(line)
End If
Next
tbNotExistingFiles.Lines = missingFiles.ToArray
I have a CSV file where I need to add new columns namely app_modulname, app_module.status, app_module.increment, app_module.success. This could easily be done with this lines of codes below.
Dim csvData = File.ReadLines(filename).Select(Function(line, index)
If(index = 0,
line + ",app_module.name,app_module.status,app_module.increment,app_module.success",
line + "," + moduleName & ",inactive," & index & ",")
)
File.WriteAllLines(savePath, csvData)
For the app_module.increment column, the row data are just increment numbers. The problem is that the code above is reading the line breaks. And, I use index as the increment number. is there other way to get the index of row?
I started with the following text file:
One,"First record",Primary
Two,"Second
record",Secondary
Three,"Third record",Tertiary
I executed this code:
Dim lines As New List(Of String)
Dim lineNumber = 1
Using parser As New TextFieldParser("TextFile1.txt") With {.Delimiters = {","}}
Do Until parser.EndOfData
Dim fields = parser.ReadFields()
'Add quotes around the column that may be multiline.
fields(1) = $"""{fields(1)}"""
lines.Add(String.Join(",", fields) & "," & lineNumber)
lineNumber += 1
Loop
End Using
File.WriteAllLines("TextFile1.txt", lines)
I ended up with this text file:
One,"First record",Primary,1
Two,"Second
record",Secondary,2
Three,"Third record",Tertiary,3
I want to replace inner text of the tag of an XML file. The XML file I have is not well formed so we cannot use LINQ-TO-XML. Is there another way to accomplish this?
<conf-start ISO-8601-date="2011-05-31"><day>31</day><month>Jan</month><year>2011</year></conf-start>
Within the XML file I just want to replace Jan to 01.
Note : The month name can change in different files and also the
ISO-8601-date="2011-05-31"
Can change. So basically is it possible to find the expression to replace the above line in an invalid XML file.
i tried this,
Dim filePath As String = TextBox1.Text
Dim directory1 As String = Path.GetDirectoryName(filePath)
Dim split As String() = filePath.Split("\")
Dim parentFolder As String = split(split.Length - 2)
Dim yourXml = XDocument.Load(TextBox1.Text & "\" & parentFolder & ".xml").Root
' Change each monthname to the number of the month
For Each elem In yourXml...<conf-start>.<day>.<month>
elem.Value = DateTime.ParseExact(elem.Value, "MMMM", System.Globalization.CultureInfo.InvariantCulture).Month
Next
' save file
yourXml.Save(TextBox1.Text & "\" & parentFolder & ".xml")
but in some files i get errors such as xlink is an undeclared prefix and in some other files i get different errors
Try This
Dim y = "<conf-start iso-8601-date=""2011-05-31""><day>31</day><month>Jan</month><year>2011</year></conf-start>"
Dim Match = Regex.Match(y, "<month>([^>]*)<\/month>").Groups(1).ToString
Regex.Replace(y, Match, DateTime.ParseExact(Match, "MMM", CultureInfo.CurrentCulture).Month.ToString)
It will give you OP Like
<conf-start iso-8601-date="2011-05-31"><day>31</day><month>01</month><year>2011</year></conf-start>
try this code :
Dim ds As New DataSet
ds.ReadXml("yourXmlFile.xml")
If Not ds Is Nothing Then
ds.Tables("conf-start").Rows(0)("month") = DateTime.ParseExact(ds.Tables(0).Rows(0)("month"), "MMM", CultureInfo.CurrentCulture).Month.ToString
ds.WriteXml("yourXmlFile.xml")
End If
I am creating a for each loop to take the words from a string and place them each into a text box. The program allows for up to "9" variables What I am trying to attempt is.
Foreach word in Words
i = i +1
Varible & i = word
txtCritical1.Text = variable & i
any ideas on a way to make this work?
Have a look through the MSDN article on For Each. It includes a sample using strings.
https://msdn.microsoft.com/en-us/library/5ebk1751.aspx
So i went with a simple if statement this does the trick. Each text box is filled in.
Dim details As String = EditEvent.EditDbTable.Rows(0).Item(13).ToString()
Dim words As String() = details.Split(New Char() {"«"})
Dim word As String
For Each word In words
i = i + 1
v = word
If i = 1 Then
txtCritical1.Text = v
ElseIf i = 2 Then
txtCritical2.Text = v
ElseIf ....
ElseIf i = 9 then
txtCritical2.text = v
Else
....
End If
Next