0

Trying to use the "find" command to list of files and send as a list instead of a one line list.

expecting outcome on body of the email listing the files (see bodyHTML line as well):

file1
file2
file3

current outcome:

"file1,file2,file3" <--not want I want on the body of the email.
FOLDER="/temp"
FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)"
FILES_COUNT=$($FILES | wc -l)


    EMAIL_TO="###"
    FROM_EMAIL="###"
    FROM_NAME="TEST"
    SUBJECT="TEST"
    TODATE=$(date "+ %D %T")
    
    bodyHTML="<div><H2 style='color:grey;'>$FILES_COUNT Total new files on $TODATE</H2><Table border=1 cellpadding=5 cellspacing=0><TR bgcolor=white align=left><TD><B>$FILES</B></TD></TR>"

    maildata='{"personalizations": [{"to": [{"email": "'${EMAIL_TO}'"}]}],"from": {"email": "'${FROM_EMAIL}'", 
        "name": "'${FROM_NAME}'"},"subject": "'${SUBJECT}'","content": [{"type": "text/html", "value": "'$bodyHTML'"}]}'

    curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'Authorization: Bearer '$SENDGRID_API_KEY \
    --header 'Content-Type: application/json' \
    --data "'$maildata'"

When I use:

FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)"

echo $FILES

outcome: 
/temp/test.txt /temp/tes2.txt /temp/test3.txt /temp/test4.txt /temp/test5.txt

When I don't use echo before $FILES:

$FILES
outcome: 
Endless loop of the follow below:

"/temp/test1.txt: line 88: +oAtMghU1YTaI+6doyj1Z7cALL5ATHPmrxLQweNYFv2S7WuIryTq9k+LaiQnDo9/: No such file or directory"
Toto
  • 89,455
  • 62
  • 89
  • 125
kurama
  • 3
  • 2

2 Answers2

0

I honestly don't unterstand your result. But if you want to put the list auf found files into the variable FILES you have to execute the find and assign it's output like you allready do with the FILES_COUNT. And not assign the command as string.

So changing this:

FILES="sudo find $FOLDER/*.txt -cmin -60 -type f"

to this

FILES=$(sudo find $FOLDER/*.txt -cmin -60 -type f)

might do the trick.

At least this simplified example returns the desired output:

ls -1
file1
file2
file3
FILES=$(find * -type f)
echo $FILES
file1 file2 file3
evilive
  • 916
  • 1
  • 7
  • 24
  • Thank you for taking a look. So I'm trying to only find files older then 60 minutes. I cannot get the output formatted the way I want. "ls -l" works but how can I use this and only find files older then 60 minutes? – kurama May 28 '21 at 20:47
  • The solution/Problem should be Independent of the search condition for the Find command. You can omit the -1, it's Just an example anyway – evilive May 28 '21 at 21:14
0

Did you edit?
FILES="sudo find $FOLDER/*.txt -cmin -60 -type f" is just a string...
Did you mean FILES=$(sudo find $FOLDER/*.txt -cmin -60 -type f) ?

The simple answer is that your problem is here: <B>${FILES[*]}</B>
You are sending the list of files in HTML, which cares not one bit about the embedded newlines. Your <B>...</B> tags appear only once, at the beginning and end of the list.

Assuming your filenames are perfect and pristine with no embedded spaces or anything that will cause this logic to crash and burn, then for a quick and dirty solution, try this -

sed -E 's/^(.*)$/<b>\1<\/b>/g' <<< "$FILES"

You should probably just be assigning with

# DEFINITELY keep the quotes *around* the subshell...
FILES="$(sudo find /temp/*.txt -cmin -60 -type f | sed -E 's/^(.*)$/<b>\1<\/b>/g')"

then instead of <B>${FILES[*]}</B>, just use $FILES.

You aren't using an array, btw. ${FILES[*]} isn't buying you anything here.
FILES is just one big string with all the filenames in it, terminated individually by newlines as returned from the find.

$: x="1
> 2
> 3"
$: echo $x # unquoted strips the formatting (the embedded newlines)
1 2 3
$: echo "$x"
1
2
3
$: echo "${x[*]}" # this is almost never what you want
1
2
3
$: echo "[${x[0]}] [${x[1]}] [${x[2]}]"
[1
2
3] [] []
$: echo "[${x:2:2}]" # if you want substrings, use this (var:start:length)
[2
]

# what we did above:
$: sed -E 's/^(.*)$/<b>\1<\/b>/g' <<< "$x"
<b>1</b>
<b>2</b>
<b>3</b>

Do look carefully at the sections on find in https://mywiki.wooledge.org/ParsingLs though. I'd probably make the list with a glob and then carefully check the properly quoted filenames with stat, personally.

Good luck.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
  • When I tried your solution "FILES="$(sudo find /temp/*.txt -cmin -60 -type f | sed -E 's/^(.*)$/\1<\/b>/g')" I'm getting a endless loop with "no such file in directory" errors. – kurama Jun 01 '21 at 14:12
  • What does the `find` give you without the `sed`? – Paul Hodges Jun 01 '21 at 14:57
  • it's giving the same results. – kurama Jun 01 '21 at 15:04
  • Then fix the `find`. `FOLDER="/temp"; FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)"` is from your code. did you mean `/tmp`? – Paul Hodges Jun 01 '21 at 15:59
  • I have a folder called "/temp". I'm not sure why when I do FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)" I get a endless loop, but when I use FILES="sudo find $FOLDER/*.txt -cmin -60 -type f" I get the files i need but just not listing in new line when I pass $FILES to HTML body. Instead of listing the files in the email it is outputting the command "sudo find $FOLDER/*.txt -cmin -60 -type f" on the email itself... – kurama Jun 01 '21 at 17:13
  • Please edit your post to *show* the assignment `FILES="sudo find $FOLDER/*.txt -cmin -60 -type f"` followed by `echo "$FILES"` and the output. – Paul Hodges Jun 01 '21 at 18:39
  • `$FILES` without the echo attempts to execute the first file with the others as arguments, and the contents of the file are not valid `bash` commands. In your command, you used the `$()` construct (that wasn't in your comment) and it works fine. without that, `FILES="sudo find $FOLDER/*.txt -cmin -60 -type f"` just assigns `sudo find $FOLDER/*.txt -cmin -60 -type f` as a string in `FILES`. – Paul Hodges Jun 02 '21 at 13:08