0

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,

SENT_1593129066_edb8ff571bc493cb700c3ae6ccfa5869__HDR.tex_
SENT_1593129143_db550b5fa1578ba40c952dac10b9b779__HDR.tex_
SENT_1593129190_00d69a5407bb6f394609f1d387573e2e__HDR.tex_

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  ;  }
gg SENT

1593129066
1593129143
1593129190

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 | \
 tee 
  >(echo "<FILENAME_LIKE_'SENT_1593130907_....tex'>" ) 
  >(cut -d'_' -f 2 | { read gmt ; date -d "$gmt"; } )  ; 
}

START OF QUESTION

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:

https://askubuntu.com/questions/833070/how-would-i-pass-the-output-of-one-command-to-multiple-commands

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

https://stackoverflow.com/questions/20871534/concatenate-in-bash-the-output-of-two-commands-without-newline-character?noredirect=1&lq=1


SUMMARY

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.


EDIT

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 | \
 paste  
  <(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"; } )  ; 
}
2
  • 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. Commented 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
    Commented Jun 29, 2020 at 17:25

1 Answer 1

2

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 ; 
     do 
       TS=$( echo "$LINE"| cut -d_ -f 2 ) ; 
       TSD=$( date  -d @$TS ) ;
       printf "%s (%s)\n"  "$LINE" "$TSD"  ;
     done
    )

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)")"}'
2
  • 1
    Or using another 'programming' language available almost everywhere bash is: ... | awk -F_ '{print $0" ("strftime("%c",$2)")"}' (other formats available per manual) Commented 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
    Commented Jun 29, 2020 at 16:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .