grep command to find files - linux

I'm looking for a command that use grep to search in /usr/bin for all the files who have 2 links and sort them in ascending.
The second command I'm looking for must use the first one and display just the files that contain the "x"
Thanks you

You can do this direct from grep, eg:
grep -r --include=*.py "HOSTS" .
will search recursively ('-r') under the current directory ('.') in all python files ('*.py') for the string "HOSTS".

This would do
find /usr/bin -links 2 -print0 | xargs -0 ls -adltr
modify the ls to do the sorting you require
find /usr/bin -links 2 -print0 | xargs -0 grep -l "x"
Files containing the "x" :)
If you meant: 'contain the x' as 'are executable (x appears in ls -l output), use
find /usr/bin -links 2 -executable -print0 | ls -adltr
To see only dirs:
find /usr/bin -links 2 -type d -executable -print0 | ls -adltr
To see only files:
find /usr/bin -links 2 -type f -executable -print0 | ls -adltr
Note: directories get 2 links by default (. is a link) so you might want to look for -links 3 with directories

Related

UNIX: Use a single find command to search files larger than 4 MiB, then pipe the output to a sort command

I currently have a question I am trying to answer below. Below is what I have come up with, but doesn't appear to be working:
find /usr/bin -type f -size +4194304c | sort -n
Am I on the right track with the above?
Question:
Use a single find command to search for all files larger than 4 MiB in
/usr/bin, printing the listing in a long format. Pipe this output to a sort command
which will sort the list from largest to smallest
I'd fiddle with for -printf command line switch, sth like this:
find YOUR_CONDITION_HERE -printf '%s %p\n' | sort -n: %s stands for size in bytes, %p for file name.
You can trim the sizes later, e.g. using cut, e.g.:
find -type f -size +4194304c -printf '%s %p\n' | sort -n | cut -f 2 -d ' '
But given the fact you need the long list format, I guess you'll be adding more fields to printf's argument.
Related topic: https://superuser.com/questions/294161/unix-linux-find-and-sort-by-date-modified
You are on the right track, but the find command will only output the name of the file, not it's size. This is why sort will sort them alphabetically.
To sort by size, you can output the file list and then pass it to ls with xargs like this:
find /usr/bin -type f -size +4194304c | xargs ls -S
If you want ls to output the file list on a single column, you can replace the -S with -S1. The command would become:
find /usr/bin -type f -size +4194304c | xargs ls -S1
To make your command resistant to all filenames, I would suggest using -print0 (it will separate paths with the null character which is the only one that cannot appear in a filename in Linux). The command would become:
find /usr/bin -type f -size +4194304c -print0 | xargs -0 ls -S1
You could also try
find /usr/bin -type f -size +4194304c -ls | sort -n -k7
and if you want the results reversed then try
find /usr/bin -type f -size +4194304c -ls | sort -r -n -k7
Or another option
find /usr/bin -type f -size +4194304c -exec ls -lSd {} +

See if directory rec is used as symlink in Linux

I want to see, if a symlink points to a directories in a specific dir - recursively.
Of course, I clould use
find / -type l -ls 2>/dev/null |grep /targetpath
But I do not want type all the (recurse) paths.
So I put all symlinks on my system into a file once.
find / -type l -ls 2>/dev/null >~/symlinks.txt
Then I list the directories recursively.
find /targetpath to start/ -maxdepth 2 -type d
And that is my question:
Can I pipe these paths from the last command to grep?
Grep should look into my file symlinks.txt and show the linecontent of matching lines (could be more symlinks pointing to this DIR)
I tried something like
find /targetpath to stat/ -maxdepth 2 -type d | xargs -0 -ifoo grep foo symlinks.txt
But it does not do, what I expect.
Or maybe an other, better solution?
From man find:
-lname pattern
File is a symbolic link whose contents match shell pattern pattern. [...]
Try:
find / -lname '*/targetpath/*'
See find-all-symlinks-to-a-directory-and-change-target-to-another-directory.

Bash - listing programs in all subdirectories with directory name before file

I don't need to do this in one line, but I've only got 1 line so far.
find . -perm -111 +type f | sort -r
What I'm trying to do is write a bash script that will display the list of all files in the current directory that are executable (z to a). I want the script to do the same for all subdirectories. What I'm having difficulty doing is displaying the name of the subdirectory before the list of executable files in that directory / subdirectory.
So, to clarify, desirable output might look like this:
program1
program2
SubDir1
program3
SubDirSubDir2
program4
SubDir2
program5
What I have right now (the above code) does this. Its not removing /path and it isn't listing the name of the new directory when directories are changed.
./exfile
./test/exfile1
./test1/program2
./test1/program
./first
Hopefully that was clear.
This will work.
I changed the permission to -100 because maybe some programs are only executable by its owner.
for d in $(find . -type d); do
echo "in $d:"
find $d -maxdepth 1 -perm -100 -type f | sed 's#.*/##'
done
This will do the trick for you.
find . -type d | sort | xargs -n1 -I{} bash -c "find {} -type f -maxdepth 1 -executable | sort -r"
The first find command lists all directories and sub directories and sort them in ascending order.
The sorted directories/sub-directories are then passed to xargs which calls bash to find the files within the directory/sub-directory and sort them in descending order.
If you prefer to also print the directory, you may run it without -type f.
You can use find on all directories and combine it with -print (to print the directory name) and -exec (to execute a find for files in that directory):
find . -type d -print -exec bash -c 'find {} -type f -depth 1 -perm +0111 | sort -r' \;
Let's break this down. First, you have the directory search:
find . -type d -print
Then the command to execute for each directory:
find {} -type f -depth 1 -perm +0111 | sort -r
The -exec switch will expand the path wherever it sees {}. Because this uses a pipe operator that is shell syntax, the whole thing is wrapped in bash -c.
You can expand on this further. If you want to strip the directory name off the files and space our your results nicer, something like this might suffice:
find {} -type f -depth 1 -print0 -perm +0111 | xargs -n1 -0 basename | sort -r && echo
Hmm, the sorting requirement makes this tricky - the "for d in $(find...)" command is clever, but hard to control the sorting. How about this? Everything is z->a, including the directories, but the awk statement is a bit of a monster ;_)
find `pwd` -perm 111 -type f |
sort -r |
xargs -n1 -I{} sh -c "dirname {};basename {}" |
awk '/^\// {dir=$0 ; if (dir != lastdir) {print;lastdir=dir}} !/^\// {print}'
Produces
/home/imcgowan/t/t3
jjj
iii
hhh
/home/imcgowan/t/t2
ggg
fff
eee
/home/imcgowan/t/t1
ddd
ccc
bbb
/home/imcgowan/t
aaa

How to find the latest executable file in a directory

I'm on linux an I want to know how to find the latest executable file in a directory?
I already know how to find the latest with:
ls -rt1 | tail -1
but how to filter out executable files?
EDIT:
I found a solution:
find path/to/dir/myfile* -perm /u=x,g=x,o=x -mtime 0 | tail -1
is this save? or is there a better solution??
Given the basic find command to look for files starting on current directory:
find . -type f
Let's add functionalities:
To find executables you can use the -executable option:
find . -type f -executable
To just find on one level of depth, that is, not within subdirectories, use the -maxdepth 1 option:
find . -maxdepth 1 -type f
To find last modified file in a directory, you can use How to recursively find the latest modified file in a directory?:
find . -type f -printf '%T# %p\n' | sort -n | tail -1 | cut -f2- -d" "
All together, this looks for last modified executable file in one level depth:
find . -maxdepth 1 -type f -executable -printf '%T# %p\n' | sort -n | tail -1 | cut -f2- -d" "

List all files in a directory with abosolute paths (excluding directories)

I've currently got:
ls -1 $(pwd)/*
Gives me all the files in a directory with absolute paths - but formats it with the directory at the start of each list of files.
Is there a way just to get a list of files in a directory recursively (absolute paths) - excluding the directory/sub-directories themselves?
find $(pwd) -type f -print
or
find $(pwd) -type f -ls
If you are feeding it into something else, you might want -print0 (to handle filenames with spaces).
E.g.: find . -type f -print0 | xargs --null --no-run-if-empty grep

Resources