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 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 Commented Jun 29, 2020 at 16:55

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.