'How to find the most recent file containing a particular text in Unix?
I've a directory with thousands of files, many of them containing the text I'm looking for. I've to search only in a single directory. I need to find the most recently created file in the directory that contains a particular text, say "check".
I've tried grep, find and ls, but I can either find a list of files containing the text e.g.
find . -type f -exec grep -l check {} +
or, the latest file in a directory using:
ls -t1 | head -n 1
How can I combine both to get the latest file containing a particular text?
Solution 1:[1]
This is a simple way to do this:
find . -type f -exec grep -l check {} + | xargs ls -latr
Solution 2:[2]
Here's a decent way to do it:
grep -Pl '<PATTERN>' <DIR> -R \
| xargs stat \
| grep '(Change:|File:)' -P \
| sed -r 's/^\s*//; s/File:.*\s(.*)`/\1/; '"s/'$//;"'s/Change:(.*)$/\1*/' \
| tr -d '\n' \
| tr '*' '\n' \
| awk '{printf "%s %s %s\n", $3, $2, $1; }' \
| sort -unr
Where <PATTERN> is the text you want to find and <DIR> is the path you want to look in.
Step-by-Step
- Grep
-Rsearch recursively and follow symlinks.-PPATTERNcan be a perl regexp.-lonly print the names of files containing a match
- Xargs
- xargs will run
statagainst each line of input coming fromSTDIN, which is the output from grep.
- xargs will run
- Grep
-Pallow perl regexp inPATTERN.
'(Change:|File:)'
We only want the filename and modification time fromstat.
Sed
-renables support for extended regular expressions
s/^\s*//
Deletes all whitespace from the start of each line.s/File:.*\s(.*)/\1/
Replace
File:, any immediate whitespace, and ` with the contents of group 1(.*)s/'$//
Delete the single-quote from lines ending with one.s/Change:(.*)$/\1*/
DeleteChange:and add a*† at the end of each line.
- Tr
-ddelete the character instead of replacing it.
'\n'
Delete newlines'*' '\n'
Replace asterisks with newlines.
- Awk
- Print output like so
HH:MM:SS.MS DATE FILE
- Print output like so
- Sort
-udiscard duplicate lines
We only want each file to appear once--we don't care how many times the pattern has appeared in the files.-ncompare according to string numerical value
We're comparing timestamps.-rreverse the result of comparisons
So the most recent file is at the top instead.
† I use * here because none of the files in my use-case had an asterisk in their name. You can use whatever character you like, so long as it doesn't appear in any of the filenames or in the output from stat.
Solution 3:[3]
May be a late response, hope this helps someone later.
I am not a pro in Shell, but found below one works for me and this is very simple to use and understand.
grep '<Search String>' $(ls -t1 | head -n 1)
Solution 4:[4]
props is not available in useEffect scope.
You must pass it as a dependency in useEffect.
Try following:
useEffect(() =>{
console.log(props.questions)
console.log(Object.values(props.questions))
checkAnswer()
}, [props])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Alexej Magura |
| Solution 3 | Ram |
| Solution 4 | Shreekesh Murkar |
