0
#! /bin/bash

while :
do
    filenames=$(ls -rt *.log | tail -n 2)
    echo $filenames
    cat $filenames > jive_log.txt
    sleep 0.1
done

I am trying to read latest 2 files from a directory and join them using bash. However when no files are present in the current directory with an extension .log the command ls -rt *.log fails with error "ls: cannot access *.log: No such file or directory". After the error it looks like the while loop does not execute. AfterWhat do I do so that the infinite loop continues even if one command fails.

3
  • 1
    Ignore errors using filenames=$(ls -rt *.log 2>/dev/null | tail -n 2) Commented Jun 13, 2014 at 9:44
  • 1.) Use find instead of ls. 2.) Bash exits only if the errexit option set -e is used. 3.) Use set -x to debug your script. Commented Jun 13, 2014 at 9:46
  • I am using ls -rt so that I can get the 2 newest files. I suppose find does not support this. Also, tried the set +e, but still did not work. Commented Jun 13, 2014 at 9:54

2 Answers 2

1

I'm not sure what you mean but perhaps:

for (( ;; )); do
    while IFS= read -r FILE; do
        cat "$FILE"
    done < <(exec ls -rt1 *.log  | tail -n 2) >> jive_log.txt
    sleep 1
done

Note the ls option -1 which prints out files line by line.

Anyhow you can join last two files to jive_log.txt with:

while IFS= read -r FILE; do
    cat "$FILE"
done < <(exec ls -rt1 *.log  | tail -n 2) >> jive_log.txt

Another way is to save it to an array (e.g. with readarray) then pass the last 2 elements to cat.

readarray -t FILES < <(exec ls -rt1 *.log)
cat "${FILES[@]:(-2)}" > jive_log.txt  ## Or perhaps you mean to append it? (>>)
Sign up to request clarification or add additional context in comments.

2 Comments

"done <(exec ls -rt1 *.txt | tail -n 2) >> jive_log.txt" throws error. syntax error near unexpected token `<(exec ls -rt *.log | tail -n 2)'
Yeah I forgot to add another <. Please see update.
1

If you want to sort the output of find, you have to add a sort key at the beginning, which can be removed later on.

find . -name \*.log -printf '%T+\t%p\n' |
sort -r |
head -2 |
cut -f 2-

Using head instead of tail is a bit cheaper.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.