This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
TheJebForge's profile picture

fs.find() problem

Started by TheJebForge, 05 November 2014 - 06:32 PM
TheJebForge #1
Posted 05 November 2014 - 07:32 PM
Im making search.
There's the piece of code which not working:

whatToSearch = read()
files = fs.find(whatToSearch)
print(#files)
if #files > 0 then
...
else
print("Nothing found!")
end
When im searching a file that really exists, the files massive have nothing!

Maybe i don't even know how does fs.find works!

Guys, help!
Edited on 05 November 2014 - 06:51 PM
KingofGamesYami #2
Posted 05 November 2014 - 07:46 PM
Try

fs.find( "/*" .. whatToSearch )
TheJebForge #3
Posted 05 November 2014 - 07:48 PM
Still not working
MKlegoman357 #4
Posted 05 November 2014 - 07:49 PM
What search term are you inputting? Also, where is the file that you are looking for placed?
TheJebForge #5
Posted 05 November 2014 - 07:51 PM
Searching for Desktop.lua (His location: /NxOS/Desktop.lua), but returns Nothing found!
Bomb Bloke #6
Posted 05 November 2014 - 11:09 PM
In that situation, you'd need to use:

fs.find( "/*/" .. whatToSearch )

However, fs.find() is really suited for situations where you want multiple returns - say you've got a folder filled with files (eg "save1", "save2", "save3" etc) and you want to get all of them, it's a handy shortcut for doing so.

If you want to search for a file and don't know how many levels deep it's buried in the file system, you really need to do some looping with fs.list(). Eg:

local function searchFor(searchTerm, searchDir)
	searchTerm = searchTerm:lower()  -- Assuming you want a case-insensitive search
	searchDir = searchDir or ""  -- If the directory to search wasn't specified, start at the root of the drive.

	local dirContents = {fs.list(searchDir)}
	dirContents[1].path = searchDir
	
	while #dirContents > 0 do
		local thisDir, thisDirIndex = dirContents[#dirContents], #dirContents
		
		for i=1,#thisDir do
			local combined = fs.combine(thisDir.path,thisDir[i])
		
			if thisDir[i]:lower() == searchTerm then
				return combined
			elseif fs.isDir(combined) then
				dirContents[#dirContents+1] = fs.list(combined)
				dirContents[#dirContents].path = combined
			end
		end
		
		table.remove(dirContents, thisDirIndex)
	end
end

print(searchFor(read()))
Edited on 05 November 2014 - 10:14 PM
TheJebForge #7
Posted 07 November 2014 - 05:10 AM
I hope that should work. I can't test it now, I am using the phone.
TheJebForge #8
Posted 07 November 2014 - 07:28 PM
In that situation, you'd need to use:

fs.find( "/*/" .. whatToSearch )

However, fs.find() is really suited for situations where you want multiple returns - say you've got a folder filled with files (eg "save1", "save2", "save3" etc) and you want to get all of them, it's a handy shortcut for doing so.

If you want to search for a file and don't know how many levels deep it's buried in the file system, you really need to do some looping with fs.list(). Eg:

local function searchFor(searchTerm, searchDir)
	searchTerm = searchTerm:lower()  -- Assuming you want a case-insensitive search
	searchDir = searchDir or ""  -- If the directory to search wasn't specified, start at the root of the drive.

	local dirContents = {fs.list(searchDir)}
	dirContents[1].path = searchDir
	
	while #dirContents > 0 do
		local thisDir, thisDirIndex = dirContents[#dirContents], #dirContents
		
		for i=1,#thisDir do
			local combined = fs.combine(thisDir.path,thisDir[i])
		
			if thisDir[i]:lower() == searchTerm then
				return combined
			elseif fs.isDir(combined) then
				dirContents[#dirContents+1] = fs.list(combined)
				dirContents[#dirContents].path = combined
			end
		end
		
		table.remove(dirContents, thisDirIndex)
	end
end

print(searchFor(read()))
Bomb how to use it? I know that it returns text. I tested and it returns a massive! For example searching for help, #result = 8! How to get these? result[1-8] not working!
MKlegoman357 #9
Posted 07 November 2014 - 10:42 PM
It returns one result: the path to the file/folder it found.
Bomb Bloke #10
Posted 07 November 2014 - 11:18 PM
Indeed, treat "result" as an eight character string, not as a table:

print(result)

My example function is rigged to return as soon as it finds a match for your target filename. If you want multiple matches, it'd go something like this:

local function searchFor(searchTerm, searchDir)
	local results = {}  -- *** Define a table for our multiple results
	
	searchTerm = searchTerm:lower()  -- Assuming you want a case-insensitive search
	searchDir = searchDir or ""  -- If the directory to search wasn't specified, start at the root of the drive.

	local dirContents = {fs.list(searchDir)}
	dirContents[1].path = searchDir

	while #dirContents > 0 do
		local thisDir, thisDirIndex = dirContents[#dirContents], #dirContents

		for i=1,#thisDir do
			local combined = fs.combine(thisDir.path,thisDir[i])

			if thisDir[i]:lower() == searchTerm then
				results[#results+1] = combined  -- *** Stick each result in the table
			elseif fs.isDir(combined) then
				dirContents[#dirContents+1] = fs.list(combined)
				dirContents[#dirContents].path = combined
			end
		end

		table.remove(dirContents, thisDirIndex)
	end
	
	return unpack(results)  -- *** Return any results found
end

local matches = {searchFor(read())}

for i=1,#matches do print(matches[i]) end
TheJebForge #11
Posted 08 November 2014 - 09:19 PM
Thanks! It works