How to find a file without showing "/"

0

im a beginner and I have no idea about the syntaxe of script shell Linux.

I have to show only files ending with (.sh) which is already done.

but these file ending with (.sh) their names has to be without ".sh" and "./" shown, when I used cut

I took everything between the two points

Exemple : ./hello.sh

output : /hello

so the " / " is still there and I didn't find any solution about it

Hello,

Welcome to the forum ! We hope you find this to be a friendly and helpful place, and that you enjoy your time here.

The explanation for this behaviour is that the find command will always return the full path to what it finds, relative to the path it is told to start its search from.

Let's demonstrate with a test. Imagine that we have the following directory on a system, from which we wish to start searching for something with find:

$ pwd
/home/unixforum/385357/find-test
$ 

Now, if we give the full path to this directory to find, we'll get an absolute path for each of our results, like so:

$ find /home/unixforum/385357/find-test -type f -name "test.*"
/home/unixforum/385357/find-test/dir1/test.doc
/home/unixforum/385357/find-test/dir1/subdir1/test.txt
/home/unixforum/385357/find-test/dir3/test.jpeg
/home/unixforum/385357/find-test/dir2/test.xlsx
/home/unixforum/385357/find-test/dir2/subdir1/test.xlsx
$

But if we start our find from within /home/unixforum/385357/find-test, and use the current directory as the root of our find path, our results instead look like this:

$ pwd
/home/unixforum/385357
$ find . -type f -name "test.*"
./find-test/dir1/test.doc
./find-test/dir1/subdir1/test.txt
./find-test/dir3/test.jpeg
./find-test/dir2/test.xlsx
./find-test/dir2/subdir1/test.xlsx
$ 

So now, we get a relative path, rather than an absolute path - that is, a valid path to our results, but only if taken from the current working directory (which is what we told find our search path was).

In summary, then: the find command will always return the filesystem path to your search results starting from the top of the given search path, and not merely the filenames of what it finds. This allows the results returned to be validly and simply used with other commands, scripts or programs, since a filename on its own without the path to where it lives isn't really useful for much.

If you really do genuinely only want the filenames for some reason, and not the full path to whatever was found, you could do this instead:

$ find /home/unixforum/385357/find-test/ -type f -name "test.*" -printf "%f\n"
test.doc
test.txt
test.jpeg
test.xlsx
test.xlsx
$ 

Here, we use the -printf argument to format our results, and we specify that we only wish to print the filename, represented by %f. Note that this requires GNU find in order to work, which is what you'll be using if you're on Linux (which your question implies you are).

Hope this helps ! If not, or if you have any further questions, please let us know and we can take things from there.

2 Likes

Thank you it worked, i don't need it personally it's just an exercise and im following it, now I need to put the file names in descending order do u have any idea ? (sort -r) doesn't work

Hello,

One thing before we go any further - if this is related to coursework or academic work of any kind, then (as per the rules you see when you first create a post) this really should have been specified up-front and made clear, as there are specific rules on precisely how we can help you in that situation. We're certainly happy to continue to assist you, but that assistance will take the form of advice and suggestions to lead you in the right direction towards a solution, rather than demonstrating a solution for you. Consequently, I've moved this topic to the "Homework & Coursework Questions" category, which is where I think it more properly belongs.

Regarding your need to reverse the results - can you show us exactly what you're currently attempting to do that (as in, the command you are typing, and the exact output you get) ? The command you provide - sort -r - is certainly a pretty standard way to sort input in reverse order, so you've definitely got the beginnings of a solution there. But if you can show us precisely how you're trying to use find and sort together, then we may be able to suggest where you need to look next.

It's not really a homework or anything like that im just learning alone following some exercises im willing start studying in a uni few months later

also my problem is only the syntaxe and the functions that I could use to get a specific result, I have a decent knowledge in algorithme and data base but im struggling because I never used linux, only windows

Hello,

OK - I think we'll continue on the current basis however, and try to help you towards finding a solution. Now, if you can provide the information that I'd suggested might be helpful in my previous post - which to recap, is the exact command or code you're using to try to get your find results reversed by using sort, which is what you'd mentioned you were trying to use - then we can take it from there and see what we can do for you.

I send you a screen shot

Hi,

Ah, thank you, I see that now, my apologies. You're very nearly there with that one. You are correctly piping the output of find into sed, and then from there in to sort. There's just a slight syntax error in your use of sort.

To point you in the right direction: just like find (and most other UNIX commands), options and flags for sort are usually given preceded by a dash character. So for example, to sort in numerical order, the command would be sort -n. Compare that with what you're using here, and see if you can spot what needs fixing.

oh man how didn't i see that ? i know that it's sort -r but I didn't check if i typed that in the right way XD

1 Like

can i ask you one last question pls ?

what does this exactly mean ? he wants me to count the number of files and folders in the current directory and its sub folders or for each file i should print a number for each file and folder ?

Hello,

I would interpret that to mean that your script countfiles.sh is expected to print just the number of files and sub-directories found beneath the current working directory, and not the actual names of the files and sub-directories which were found.

You can do that most easily by combining the output of find with another command, one that is quite often used to produce a count of the number of lines of text in its input. Have a think, and see if you know of or can discover a command that can do that. Once you do, then it's a matter of linking find up with that command via a pipe, and using that command (with the appropriate flags, if such are required), and you should be able to get the output you need.

I suppose that it's count i'll search for it

Hi,

OK, great ! If you do have any further specific issues with this particular question, feel free to come back again, demonstrating what you've tried, what the output is, and giving us a description of the problem. Otherwise of course if you have any further questions about other things in the future, you can of course create a new thread to discuss those as well. Good luck !

I think I found it but what's the error ?

I switched to this one now but it's not right

Hello,

You could in theory do this with tree, but there's a far simpler method. Do you know the command you would typically use to get a word count for a file ? If you do, you could use that here instead.

Now, as it happens, this is actually a good opportunity to introduce you to another command - apropos. This is kind of a man-page index utility, more or less. You can use it to find out what command might be useful for certain tasks, when you don't know the name of the command itself.

For example, let's say we wanted to know which Linux command we could use to partition a disk. We could do this:

$ apropos 'disk partition'
cfdisk (8)           - display or manipulate disk partition table
fdisk (8)            - manipulate disk partition table
partx (8)            - tell the Linux kernel about the presence and numbering of on-disk partitions
$ 

And there we go - three possibilities for us to explore. To get in-depth information on one of them (cfdisk, say), you would then type man cfdisk to read the on-line manual page (or man page, for short), and be able to learn more about it.

So, if you don't know what command you could use to do a word count on a text file (which you could then also pipe the output of find into, and get it to count that as its input), try maybe looking at apropos count and see if anything jumps out at you as a likely word counting candidate.

Hope this helps !

Hi,

Ah, I see you have it - wc -l is indeed exactly what we need here. Looking again at my earlier find test, by way of an example:

$ find /home/unixforum/385357/find-test/ -type f -name "test.*" -printf "%f\n"
test.doc
test.txt
test.jpeg
test.xlsx
test.xlsx
$ find /home/unixforum/385357/find-test/ -type f -name "test.*" -printf "%f\n" | wc -l | cat -e
5$
$ 

We can see if we count the lines that we find that there are indeed five results, and by piping the results into wc -l we do indeed get a count of those lines.

So, I'm slightly confused by why this isn't working in your case. The wc command itself can't really go wrong - it counts the number of characters, words or lines that it gets as its input, and prints that number as the output. And wc -l is definitely the right syntax for producing a line count, and nothing else. So either your find isn't finding what your tutor expects you to find, or not all the output is being properly printed, I would imagine.

1 Like

A late comment on the previous sed filter.
sed (like grep) uses RE.
A dot in a RE matches one "any character".
It must be escaped
sed 's/\.sh$//'
or put in a character set
sed 's/[.]sh$//'
to match a literal dot.

RE is very powerful but has some traps.
sed 's/[.].*$//'
The .* matches "any character any times". But it is "greedy" and will consume up to the leftmost dot.
A t1.t2.ext will become t1
An often used trick is to use a negated character set
sed 's/[.][^.]*$//'
The [^.]* matches a "not-dot character any times"
And t1.t2.ext will become t1.t2