How to grab the last result of a find command? - bash

The result of my find command produces the following result
./alex20_0
./alex20_1
./alex20_2
./alex20_3
I saved this result as a variable. now the only part I really need is whatever the last part is or essentially the highest number or "latest version".
So from the above string all I need to extract is ./alex20_3 and save that as a variable. Is there a way to just extract whatever the last directory is outputted from the find command?
I would do the last nth characters command to extract it since its already in order, but it wouldn't be the same number of characters once we get to version ./alex20_10 etc.

Try this:
your_find_command | tail -n 1

find can list your files in any order. To extract the latest version you have to sort the output of find. The safest way to do this is
find . -maxdepth 1 -name "string" -print0 | sort -zV | tail -zn1
If your implementation of sort or tail does not support -z and you are sure that the filenames are free of line-breaks you can also use
find . -maxdepth 1 -name "string" -print | sort -V | tail -n1

There could be multiple ways to achieve this -
Using the 'tail' command (as suggested by #Roadowl)
find branches -name alex* | tail -n1
Using the 'awk' command
find branches -name alex* | awk 'END{print}'
Using the 'sed' command
find branches -name alex* | sed -e '$!d'
Other possible options are to use a bash script, perl or any other language. You best bet would be the one that you find is more convenient.

Since you want the file name sorted by the highest version, you can try as follows
$ ls
alex20_0 alex20_1 alex20_2 alex20_3
$ find . -iname "*alex*" -print | sort | tail -n 1
./alex20_3

Related

terminal find file with latest patch number

I have a folder with a lot of patch files with pattern
1.1.hotfix1
1.2.hotfix2
2.1.hotfix1
2.1.hotfix2 ...etc
and I have to find out the latest patch(2.1.hotfix2 should be the result of the example) with a bash
how can i achieve it?
Reverse order all files by time and print the first line.
In case you have some other files then you can print files having hotfix text only.
ls -t1 *hotfix* | head -n 1
You can use find with regex, and take the last line from sort:
find * -type f -regex "^[^\d]+\.[^\d]+\.hotfix[^\d]+$" | sort | tail -1

How to read CSV file stored in variable

I want to read a CSV file using Shell,
But for some reason it doesn't work.
I use this to locate the latest added csv file in my csv folder
lastCSV=$(ls -t csv-output/ | head -1)
and this to count the lines.
wc -l $lastCSV
Output
wc: drupal_site_livinglab.csv: No such file or directory
If I echo the file it says: drupal_site_livinglab.csv
Your issue is that you're one directory up from the path you are trying to read. The quick fix would be wc -l "csv-output/$lastCSV".
Bear in mind that parsing ls -t though convenient, isn't completely robust, so you should consider something like this to protect you from awkward file names:
last_csv=$(find csv-output/ -mindepth 1 -maxdepth 1 -printf '%T#\t%p\0' |
sort -znr | head -zn1 | cut -zf2-)
wc -l "$last_csv"
GNU find lists all files along with their last modification time, separating the output using null bytes to avoid problems with awkward filenames.
if you remove -maxdepth 1, this will become a recursive search
GNU sort arranges the files from newest to oldest, with -z to accept null byte-delimited input.
GNU head -z returns the first record from the sorted list.
GNU cut -z at the end discards the timestamp, leaving you with only the filename.
You can also replace find with stat (again, this assumes that you have GNU coreutils):
last_csv=$(stat csv-output/* --printf '%Y\t%n\0' | sort -znr | head -zn1 | cut -zf2-)

Using the command line "find | grep -wc" how do I return values that are greater than zero?

I downloaded a .htm file and typed this in
find . -iname "*.htm" | xargs grep -Ewcp 'sevenfold'
I am unsure what the –E does but I know –wcp is word count and path. A sample of what shows up it this.
./bible/bible/RecoveryVersion_htm/ZecN.htm:1
./bible/bible/RecoveryVersion_htm/ZecO.htm:0
./bible/bible/RecoveryVersion_htm/Zep.htm:0
./bible/bible/RecoveryVersion_htm/ZepN.htm:0
./bible/bible/RecoveryVersion_htm/ZepO.htm:0
This list is rather long with many zeros how to I narrow the search to only display the ones without zeros hits for the word ? Can I somehow put an if statement “if the value is 0 don’t display“ is this possible?
You can use another invocation of grep to filter the results:
find . -iname "*.htm" | xargs grep -Ewcp 'sevenfold' | grep -v ':0$'

How to get sorted list of files by modified date that match a certain filename and print out part of text in unix shell?

Sorry for the long title. I'm trying to basically write a script that will do a "find" and get a sorted list of all files named README and print out a section of text in them. It's an easy way for me to go to a directory which has a number of project folders and print out summaries. This is what I have so far:
find . -name "README" | xargs -I {} sed -n '/---/,/NOTES/p' {}
I can't seem to get this to be sorted by modified date. Any help would be great!
You can use the -printf option in find:
$ find . -name 'README' -printf '%T#\t%p\n' | sort | cut -f 2-

How can I find and count number of files matching a given string?

I want to find and count all the files on my system that begin with some string, say "foo", using only one line in bash.
I'm new to bash so I'd like to avoid scripting if possible - how can I do this using only simple bash commands and maybe piping in just one line?
So far I've been using find / -name foo*. This returns the list of files, but I don't know what to add to actually count the files.
You can use
find / -type f -name 'foo*' | wc -l
Use the single-quotes to prevent the shell from expanding the asterisk.
Use -type f to include only files (not links or directories).
wc -l means "word count, lines only." Since find will list one file per line, this returns the number of files it found.
find / -name foo* | wc -l should do it. Here is a link to man wc. wc -l counts the number of lines
You can pipe it into wc
find / -name foo * | wc -l

Resources