Find the age of the oldest file in one line or return zero





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







4















I want to find the age of the oldest file in a certain directory or return 0 if there aren't any files in this directory. I also need a one-line command doing it. So far this is my command for finding the age in seconds of the oldest file in the directory:



expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))


The problem is that if there are no files it is returning the following error:



$ expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))
stat: cannot stat ‘0’: No such file or directory
-bash: 1554373460 - : syntax error: operand expected (error token is "- ")


So in this case I want the command to return just 0 and to suppress the error printout.










share|improve this question


















  • 2





    Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

    – Jeff Schaller
    11 hours ago











  • I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

    – Georgе Stoyanov
    11 hours ago













  • also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

    – Georgе Stoyanov
    11 hours ago











  • ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

    – mpez0
    2 hours ago




















4















I want to find the age of the oldest file in a certain directory or return 0 if there aren't any files in this directory. I also need a one-line command doing it. So far this is my command for finding the age in seconds of the oldest file in the directory:



expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))


The problem is that if there are no files it is returning the following error:



$ expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))
stat: cannot stat ‘0’: No such file or directory
-bash: 1554373460 - : syntax error: operand expected (error token is "- ")


So in this case I want the command to return just 0 and to suppress the error printout.










share|improve this question


















  • 2





    Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

    – Jeff Schaller
    11 hours ago











  • I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

    – Georgе Stoyanov
    11 hours ago













  • also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

    – Georgе Stoyanov
    11 hours ago











  • ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

    – mpez0
    2 hours ago
















4












4








4


1






I want to find the age of the oldest file in a certain directory or return 0 if there aren't any files in this directory. I also need a one-line command doing it. So far this is my command for finding the age in seconds of the oldest file in the directory:



expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))


The problem is that if there are no files it is returning the following error:



$ expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))
stat: cannot stat ‘0’: No such file or directory
-bash: 1554373460 - : syntax error: operand expected (error token is "- ")


So in this case I want the command to return just 0 and to suppress the error printout.










share|improve this question














I want to find the age of the oldest file in a certain directory or return 0 if there aren't any files in this directory. I also need a one-line command doing it. So far this is my command for finding the age in seconds of the oldest file in the directory:



expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))


The problem is that if there are no files it is returning the following error:



$ expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))
stat: cannot stat ‘0’: No such file or directory
-bash: 1554373460 - : syntax error: operand expected (error token is "- ")


So in this case I want the command to return just 0 and to suppress the error printout.







shell-script files directory






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 11 hours ago









Georgе StoyanovGeorgе Stoyanov

164421




164421








  • 2





    Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

    – Jeff Schaller
    11 hours ago











  • I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

    – Georgе Stoyanov
    11 hours ago













  • also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

    – Georgе Stoyanov
    11 hours ago











  • ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

    – mpez0
    2 hours ago
















  • 2





    Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

    – Jeff Schaller
    11 hours ago











  • I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

    – Georgе Stoyanov
    11 hours ago













  • also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

    – Georgе Stoyanov
    11 hours ago











  • ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

    – mpez0
    2 hours ago










2




2





Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

– Jeff Schaller
11 hours ago





Out of curiosity, why does it have to be in one line? It's much less readable & maintainable that way.

– Jeff Schaller
11 hours ago













I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

– Georgе Stoyanov
11 hours ago







I am passing this line to specialized software. Then according to the output of the command, I can trigger an alarm and if I make it on more than a single line, I need to write more complex logic. The idea is to check a specific directory where there should not be any files for more than 20 seconds, I want to trigger an alarm if the age of the oldest file is more than 30 seconds.

– Georgе Stoyanov
11 hours ago















also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

– Georgе Stoyanov
11 hours ago





also I would be very happy if you have any ideas, how I can simplify my command for finding the age of the oldest file

– Georgе Stoyanov
11 hours ago













ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

– mpez0
2 hours ago







ls -lt | tail -1 will give you the oldest file; you can parse out the date or go through the stat stuff without having to do a single line shell loop

– mpez0
2 hours ago












2 Answers
2






active

oldest

votes


















4














If it must be one line:



stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'




  • stat -c %Y ./* 2>/dev/null print the timestamp of all files, ignoring errors (so no files results in no output)


  • With awk:





    • -v d="$(date +%s)" save the current timestamp in a variable d


    • BEGIN {m=d} initialize m to d


    • $0 < m {m = $0} keeping track of the minimum in m


    • END {print d - m} print the difference.








share|improve this answer


























  • unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

    – Georgе Stoyanov
    11 hours ago











  • @George ah, oops, I inverted the check for min

    – muru
    11 hours ago



















5














With zsh and perl:



perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])


(add the D glob qualifier if you also want to consider hidden files (but not . nor ..)).



Note that for symlinks, that considers the modification time of the file it resolves to. Remove the - in the glob qualifiers to consider the modification time of the symlink instead (and use (lstat$ARGV[0] && -M _) in perl to get the age of the symlink).



That gives the age in days. Multiply by 86400 to get a number of seconds:



perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])




  • (N-Om[1]): glob qualifier:



    • N: turns on nullglob for that glob. So if there's no file in the directory, expands to nothing causing perl's -M to return undef.


    • -: causes next glob qualifiers to apply on the target of symlinks


    • Om: reverse (capital) order by modification time (so from oldest to newest like ls -rt)


    • [1]: select first matching file only




  • -M file: gets the age of the content of the file.


  • 0+ or 86400* force a conversion to number (for the undef case).






share|improve this answer


























  • I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

    – Georgе Stoyanov
    7 hours ago








  • 1





    @GeorgеStoyanov, the syntax is for zsh, not bash.

    – Stéphane Chazelas
    6 hours ago












Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f510472%2ffind-the-age-of-the-oldest-file-in-one-line-or-return-zero%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














If it must be one line:



stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'




  • stat -c %Y ./* 2>/dev/null print the timestamp of all files, ignoring errors (so no files results in no output)


  • With awk:





    • -v d="$(date +%s)" save the current timestamp in a variable d


    • BEGIN {m=d} initialize m to d


    • $0 < m {m = $0} keeping track of the minimum in m


    • END {print d - m} print the difference.








share|improve this answer


























  • unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

    – Georgе Stoyanov
    11 hours ago











  • @George ah, oops, I inverted the check for min

    – muru
    11 hours ago
















4














If it must be one line:



stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'




  • stat -c %Y ./* 2>/dev/null print the timestamp of all files, ignoring errors (so no files results in no output)


  • With awk:





    • -v d="$(date +%s)" save the current timestamp in a variable d


    • BEGIN {m=d} initialize m to d


    • $0 < m {m = $0} keeping track of the minimum in m


    • END {print d - m} print the difference.








share|improve this answer


























  • unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

    – Georgе Stoyanov
    11 hours ago











  • @George ah, oops, I inverted the check for min

    – muru
    11 hours ago














4












4








4







If it must be one line:



stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'




  • stat -c %Y ./* 2>/dev/null print the timestamp of all files, ignoring errors (so no files results in no output)


  • With awk:





    • -v d="$(date +%s)" save the current timestamp in a variable d


    • BEGIN {m=d} initialize m to d


    • $0 < m {m = $0} keeping track of the minimum in m


    • END {print d - m} print the difference.








share|improve this answer















If it must be one line:



stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'




  • stat -c %Y ./* 2>/dev/null print the timestamp of all files, ignoring errors (so no files results in no output)


  • With awk:





    • -v d="$(date +%s)" save the current timestamp in a variable d


    • BEGIN {m=d} initialize m to d


    • $0 < m {m = $0} keeping track of the minimum in m


    • END {print d - m} print the difference.









share|improve this answer














share|improve this answer



share|improve this answer








edited 10 hours ago









Stéphane Chazelas

313k57592948




313k57592948










answered 11 hours ago









murumuru

37.2k589164




37.2k589164













  • unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

    – Georgе Stoyanov
    11 hours ago











  • @George ah, oops, I inverted the check for min

    – muru
    11 hours ago



















  • unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

    – Georgе Stoyanov
    11 hours ago











  • @George ah, oops, I inverted the check for min

    – muru
    11 hours ago

















unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

– Georgе Stoyanov
11 hours ago





unfortunately, it does return 0 no matter if the directory is empty or it has more than one file

– Georgе Stoyanov
11 hours ago













@George ah, oops, I inverted the check for min

– muru
11 hours ago





@George ah, oops, I inverted the check for min

– muru
11 hours ago













5














With zsh and perl:



perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])


(add the D glob qualifier if you also want to consider hidden files (but not . nor ..)).



Note that for symlinks, that considers the modification time of the file it resolves to. Remove the - in the glob qualifiers to consider the modification time of the symlink instead (and use (lstat$ARGV[0] && -M _) in perl to get the age of the symlink).



That gives the age in days. Multiply by 86400 to get a number of seconds:



perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])




  • (N-Om[1]): glob qualifier:



    • N: turns on nullglob for that glob. So if there's no file in the directory, expands to nothing causing perl's -M to return undef.


    • -: causes next glob qualifiers to apply on the target of symlinks


    • Om: reverse (capital) order by modification time (so from oldest to newest like ls -rt)


    • [1]: select first matching file only




  • -M file: gets the age of the content of the file.


  • 0+ or 86400* force a conversion to number (for the undef case).






share|improve this answer


























  • I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

    – Georgе Stoyanov
    7 hours ago








  • 1





    @GeorgеStoyanov, the syntax is for zsh, not bash.

    – Stéphane Chazelas
    6 hours ago
















5














With zsh and perl:



perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])


(add the D glob qualifier if you also want to consider hidden files (but not . nor ..)).



Note that for symlinks, that considers the modification time of the file it resolves to. Remove the - in the glob qualifiers to consider the modification time of the symlink instead (and use (lstat$ARGV[0] && -M _) in perl to get the age of the symlink).



That gives the age in days. Multiply by 86400 to get a number of seconds:



perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])




  • (N-Om[1]): glob qualifier:



    • N: turns on nullglob for that glob. So if there's no file in the directory, expands to nothing causing perl's -M to return undef.


    • -: causes next glob qualifiers to apply on the target of symlinks


    • Om: reverse (capital) order by modification time (so from oldest to newest like ls -rt)


    • [1]: select first matching file only




  • -M file: gets the age of the content of the file.


  • 0+ or 86400* force a conversion to number (for the undef case).






share|improve this answer


























  • I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

    – Georgе Stoyanov
    7 hours ago








  • 1





    @GeorgеStoyanov, the syntax is for zsh, not bash.

    – Stéphane Chazelas
    6 hours ago














5












5








5







With zsh and perl:



perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])


(add the D glob qualifier if you also want to consider hidden files (but not . nor ..)).



Note that for symlinks, that considers the modification time of the file it resolves to. Remove the - in the glob qualifiers to consider the modification time of the symlink instead (and use (lstat$ARGV[0] && -M _) in perl to get the age of the symlink).



That gives the age in days. Multiply by 86400 to get a number of seconds:



perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])




  • (N-Om[1]): glob qualifier:



    • N: turns on nullglob for that glob. So if there's no file in the directory, expands to nothing causing perl's -M to return undef.


    • -: causes next glob qualifiers to apply on the target of symlinks


    • Om: reverse (capital) order by modification time (so from oldest to newest like ls -rt)


    • [1]: select first matching file only




  • -M file: gets the age of the content of the file.


  • 0+ or 86400* force a conversion to number (for the undef case).






share|improve this answer















With zsh and perl:



perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])


(add the D glob qualifier if you also want to consider hidden files (but not . nor ..)).



Note that for symlinks, that considers the modification time of the file it resolves to. Remove the - in the glob qualifiers to consider the modification time of the symlink instead (and use (lstat$ARGV[0] && -M _) in perl to get the age of the symlink).



That gives the age in days. Multiply by 86400 to get a number of seconds:



perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])




  • (N-Om[1]): glob qualifier:



    • N: turns on nullglob for that glob. So if there's no file in the directory, expands to nothing causing perl's -M to return undef.


    • -: causes next glob qualifiers to apply on the target of symlinks


    • Om: reverse (capital) order by modification time (so from oldest to newest like ls -rt)


    • [1]: select first matching file only




  • -M file: gets the age of the content of the file.


  • 0+ or 86400* force a conversion to number (for the undef case).







share|improve this answer














share|improve this answer



share|improve this answer








edited 6 hours ago

























answered 10 hours ago









Stéphane ChazelasStéphane Chazelas

313k57592948




313k57592948













  • I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

    – Georgе Stoyanov
    7 hours ago








  • 1





    @GeorgеStoyanov, the syntax is for zsh, not bash.

    – Stéphane Chazelas
    6 hours ago



















  • I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

    – Georgе Stoyanov
    7 hours ago








  • 1





    @GeorgеStoyanov, the syntax is for zsh, not bash.

    – Stéphane Chazelas
    6 hours ago

















I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

– Georgе Stoyanov
7 hours ago







I am getting just 0 as an output even though it should show me a couple of thousands of seconds, both commands actually gives me the same output and on another machine I am getting an error: -bash: syntax error near unexpected token '(', the one giving me an error is running a rather old version of perl: v5.16.3

– Georgе Stoyanov
7 hours ago






1




1





@GeorgеStoyanov, the syntax is for zsh, not bash.

– Stéphane Chazelas
6 hours ago





@GeorgеStoyanov, the syntax is for zsh, not bash.

– Stéphane Chazelas
6 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f510472%2ffind-the-age-of-the-oldest-file-in-one-line-or-return-zero%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Callistus I

Tabula Rosettana

How to label and detect the document text images