This is a continuation of recursively sort files with string "SENT_" somewhere in filename by the substring immediately after SENT_, and then display them. Linux as I thought it was better to separate out the questions...

What I was helped with there gave me an order (by the seconds date, i.e. $(date +%s) as a substring in the file) such as,


and my goal is to, one the same line, put in parentheses the 'proper date' at the end, i.e.

SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_ (June 20, 2020 15:32:33)
SENT_1593129143_db550b5fa1578ba40c952dac10b9b779__HDR.tex_ (July 21, 2020 19:44:02)
SENT_1593129190_00d69a5407bb6f394609f1d387573e2e__HDR.tex_ (Aug 22, 2020 04:43:38)

(dates and format are made up)

So I did this to get the $(date +%s) part,

gg () { find . -type f -name "*"$@"*" -printf '%f\n' |  sort -t'_' -k2.1,2.10 | cut -d'_' -f 2  ;  }


where the cut is the only thing new from the linked page.

The 1st problem was getting it into date -d ??? but luckily I found: How do I pipe output to date -d "value"?

which said date needed a variable. So I would try this:

gg () { find . -type f -name "*"$@"*" -printf '%f\n' | \  
 sort -t'_' -k2.1,2.10 | \
  >(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  >(cut -d'_' -f 2 | { read gmt ; date -d "$gmt"; } )  ; 


My idea was to assemble the 2 parts on one line, ie for SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_ (1st part - don't have this yet) and (June 20, 2020 15:32:33) (2nd part) by using tee to pipe the output from sort to both;

  1. printing/echo the original filename, ie the first part, and
  2. the date in parenthesis, e.g. (June 20, 2020 15:32:33)

This idea, tee >(what_to_do) >(another_thing_to_do) came from:


and seems to put both parts on the same line. If not, I wonder if I'll need something like the following wrapped around the tee...? But right now it only does the 'first' >(echo...) part once...

The idea to put them on the same line, which I was thinking of using { echo "The quick"; echo "brown fox"; } | tr "\n" " " from



So I need to

  1. do the 'echo' part to recover the whole filename (preferably with the directories) and (date +%s) substring, eg ~/dir_A/dir2/SENT_1593129066_asdfasdfasdf_asdf.tex, and
  2. put them on one line, for each file found by find.

This will then be the end of the function I wanted.


This only worked once; (I don't know about paste but it would be better, but not necessary, to have more common tools...)

gg () { find . -type f -name "*"$@"*" -printf '%f\n' | \
 sort -t'_' -k2.1,2.10 | \
  <(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  <(cut -d'_' -f 2 | { read gmt ; date -d @"$gmt"; } )  ; 

Trying to fix it so far has failed;

gg () { find . -type f -name "*"$@"*" -printf '%f\n' |  \
 sort -t'_' -k2.1,2.10 | \ 
 xargs -I'{}' paste  
  <(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  <(cut -d'_' -f 2 | { read gmt ; date -d @"$gmt"; } )  ; 
  • 1
    Side note: find … -name "*"$@"*" is either a bug (if you don't have a clue) or bad practice (if you do). -name needs exactly one argument. $@ can expand to multiple arguments even if double-quoted. You should use (double-quoted) $1, unless you consciously intend to enhance the expression of find via arguments of gg (e.g. gg foo -links 1 -name bar). But even then $@ should be double-quoted. Jun 27, 2020 at 18:32
  • I don't recall why that was like that haha but from your attention I read more about it. Seems if I do want 1 argument though I would use "$*"... or what I am now using ff () { find . -type f -name "$1" -printf '%f\n' | sort -t'_' -k2.1,2.10 | ( while read LINE; do TS=$( echo "$LINE"| cut -d_ -f 2 ); TSD=$( date -d @$TS ); printf "%s (%s)\n" "$LINE" "$TSD" ; done; ); } as I will
    – nate
    Jun 29, 2020 at 17:25

1 Answer 1


Bash is a programming language ( please read man bash ) , so you can do a loop.

Example 1 :

find . -type f -name 'SENT*' -printf '%f\n' | \
   sort -t'_' -k2.1,2.10 | \
     while read LINE ; 
       TS=$( echo "$LINE"| cut -d_ -f 2 ) ; 
       TSD=$( date  -d @$TS ) ;
       printf "%s (%s)\n"  "$LINE" "$TSD"  ;

Example 2 ( reported by another user ) :

find . -type f -name 'SENT*' -printf '%f\n' | \
   sort -t'_' -k2.1,2.10 | \
   awk -F_ '{print $0" ("strftime("%c",$2)")"}'
  • 1
    Or using another 'programming' language available almost everywhere bash is: ... | awk -F_ '{print $0" ("strftime("%c",$2)")"}' (other formats available per manual) Jun 27, 2020 at 3:23
  • I actually know a little about functions and for-loops in bash (and have crammed too much in my .bashrc actually - where this will go) though I have much to learn - the scripting language guides are great but its a slow process :) tldp.org/LDP/abs/html
    – nate
    Jun 29, 2020 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.