Creating a for loop with find -exec and while

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





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








0















I am trying to make this script that loops through video files created between hours 00 and 12, convert them with ffmpeg and then remove them.



The script works in terms of finding the files and starting ffpmeg but it seems that it continues to "send" characters from the find -exec after that ffmpeg has started on the first conversion and it eventually breaks ffmpeg and stop the conversion. How can I modify the script so this does not happen?



The current script



!/bin/bash -e
find /videos/. -type f -print0 -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ;|while read -d $'' i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4
rm -f -- "$i"
done









share|improve this question
























  • If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

    – steeldriver
    Mar 11 at 17:06







  • 1





    See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

    – Gordon Davisson
    Mar 11 at 17:32












  • I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

    – Kaah
    Mar 11 at 18:27











  • ... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

    – Kaah
    Mar 11 at 18:49











  • I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

    – Kaah
    Mar 11 at 18:55

















0















I am trying to make this script that loops through video files created between hours 00 and 12, convert them with ffmpeg and then remove them.



The script works in terms of finding the files and starting ffpmeg but it seems that it continues to "send" characters from the find -exec after that ffmpeg has started on the first conversion and it eventually breaks ffmpeg and stop the conversion. How can I modify the script so this does not happen?



The current script



!/bin/bash -e
find /videos/. -type f -print0 -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ;|while read -d $'' i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4
rm -f -- "$i"
done









share|improve this question
























  • If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

    – steeldriver
    Mar 11 at 17:06







  • 1





    See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

    – Gordon Davisson
    Mar 11 at 17:32












  • I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

    – Kaah
    Mar 11 at 18:27











  • ... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

    – Kaah
    Mar 11 at 18:49











  • I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

    – Kaah
    Mar 11 at 18:55













0












0








0








I am trying to make this script that loops through video files created between hours 00 and 12, convert them with ffmpeg and then remove them.



The script works in terms of finding the files and starting ffpmeg but it seems that it continues to "send" characters from the find -exec after that ffmpeg has started on the first conversion and it eventually breaks ffmpeg and stop the conversion. How can I modify the script so this does not happen?



The current script



!/bin/bash -e
find /videos/. -type f -print0 -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ;|while read -d $'' i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4
rm -f -- "$i"
done









share|improve this question
















I am trying to make this script that loops through video files created between hours 00 and 12, convert them with ffmpeg and then remove them.



The script works in terms of finding the files and starting ffpmeg but it seems that it continues to "send" characters from the find -exec after that ffmpeg has started on the first conversion and it eventually breaks ffmpeg and stop the conversion. How can I modify the script so this does not happen?



The current script



!/bin/bash -e
find /videos/. -type f -print0 -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ;|while read -d $'' i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4
rm -f -- "$i"
done






shell-script find date ffmpeg






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 11 at 16:57









Jeff Schaller

44.8k1164146




44.8k1164146










asked Mar 11 at 16:38









KaahKaah

12




12












  • If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

    – steeldriver
    Mar 11 at 17:06







  • 1





    See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

    – Gordon Davisson
    Mar 11 at 17:32












  • I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

    – Kaah
    Mar 11 at 18:27











  • ... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

    – Kaah
    Mar 11 at 18:49











  • I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

    – Kaah
    Mar 11 at 18:55

















  • If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

    – steeldriver
    Mar 11 at 17:06







  • 1





    See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

    – Gordon Davisson
    Mar 11 at 17:32












  • I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

    – Kaah
    Mar 11 at 18:27











  • ... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

    – Kaah
    Mar 11 at 18:49











  • I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

    – Kaah
    Mar 11 at 18:55
















If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

– steeldriver
Mar 11 at 17:06






If you're trying to use the exit status of the sh -c '...' tests to filter the find results, shouldn't it go before the -print0?

– steeldriver
Mar 11 at 17:06





1




1





See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

– Gordon Davisson
Mar 11 at 17:32






See Stackoverflow: "When reading a file line by line, I only get to execute ffmpeg on the first line" and BashFAQ #89: "I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

– Gordon Davisson
Mar 11 at 17:32














I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

– Kaah
Mar 11 at 18:27





I tried moving -print0 to after sh -c '...'but I get "stat: cannot stat 'sh': No such file or directory" errors or no output or the same result depending on where I put it.

– Kaah
Mar 11 at 18:27













... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

– Kaah
Mar 11 at 18:49





... -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 13 ] && [ "$h" -lt 23 ]' sh ; -print | while read i; do ls -l "$i"works fine but when I use $i as input file for ffmpeg it goes haywire.

– Kaah
Mar 11 at 18:49













I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

– Kaah
Mar 11 at 18:55





I am testing now with adding </dev/null at the end of the ffmpeg command. So far so good.

– Kaah
Mar 11 at 18:55










1 Answer
1






active

oldest

votes


















0














Thanks to Gordon Davisson I managed to solve the problem. Here is the complete working script if someone happens to stumple upon this issue in the future.



#!/bin/bash -e
find /videos/. -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ; -print | while IFS= read -r i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4 </dev/null
rm -f -- "$i"
done





share|improve this answer























  • A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

    – Gordon Davisson
    Mar 12 at 2:03











  • I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

    – Kaah
    Mar 26 at 18:43











  • I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

    – Kaah
    Mar 26 at 18:46












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%2f505679%2fcreating-a-for-loop-with-find-exec-and-while%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Thanks to Gordon Davisson I managed to solve the problem. Here is the complete working script if someone happens to stumple upon this issue in the future.



#!/bin/bash -e
find /videos/. -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ; -print | while IFS= read -r i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4 </dev/null
rm -f -- "$i"
done





share|improve this answer























  • A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

    – Gordon Davisson
    Mar 12 at 2:03











  • I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

    – Kaah
    Mar 26 at 18:43











  • I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

    – Kaah
    Mar 26 at 18:46
















0














Thanks to Gordon Davisson I managed to solve the problem. Here is the complete working script if someone happens to stumple upon this issue in the future.



#!/bin/bash -e
find /videos/. -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ; -print | while IFS= read -r i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4 </dev/null
rm -f -- "$i"
done





share|improve this answer























  • A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

    – Gordon Davisson
    Mar 12 at 2:03











  • I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

    – Kaah
    Mar 26 at 18:43











  • I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

    – Kaah
    Mar 26 at 18:46














0












0








0







Thanks to Gordon Davisson I managed to solve the problem. Here is the complete working script if someone happens to stumple upon this issue in the future.



#!/bin/bash -e
find /videos/. -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ; -print | while IFS= read -r i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4 </dev/null
rm -f -- "$i"
done





share|improve this answer













Thanks to Gordon Davisson I managed to solve the problem. Here is the complete working script if someone happens to stumple upon this issue in the future.



#!/bin/bash -e
find /videos/. -type f -exec sh -c 'h=$(date -d @$(stat -c %Y "$1") +%-H); [ "$h" -ge 00 ] && [ "$h" -lt 12 ]' sh ; -print | while IFS= read -r i;
do
ffmpeg -y -i "$i" -vcodec libx264 -crf 27 -preset veryfast -movflags +faststart -c:a copy -threads 14 /output/"$(basename "$i" .ts)".mp4 </dev/null
rm -f -- "$i"
done






share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 11 at 19:39









KaahKaah

12




12












  • A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

    – Gordon Davisson
    Mar 12 at 2:03











  • I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

    – Kaah
    Mar 26 at 18:43











  • I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

    – Kaah
    Mar 26 at 18:46


















  • A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

    – Gordon Davisson
    Mar 12 at 2:03











  • I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

    – Kaah
    Mar 26 at 18:43











  • I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

    – Kaah
    Mar 26 at 18:46

















A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

– Gordon Davisson
Mar 12 at 2:03





A couple more recommendations occur to me: I'd move the time check into the while loop, so you're only using a single shell -- that is, have find list all files, then check the date in the loop & only run ffmpeg if it's in the right range. Also, it'd be best to make the rm conditional on ffmpeg succeeding. So it should be something like `while ... do h=$(...); [ "$h" -ge 00 ] && [ "$h" -lt 12 ] && ffmpeg ... && rm ...; done

– Gordon Davisson
Mar 12 at 2:03













I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

– Kaah
Mar 26 at 18:43





I agree with your comment Gordon. I have another issue with files modified during hour 23. For example files modified 23:45 will not be included in the list. How can I solve this?

– Kaah
Mar 26 at 18:43













I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

– Kaah
Mar 26 at 18:46






I solved it by using the '-le' operator listed here: tldp.org/LDP/abs/html/comparison-ops.html

– Kaah
Mar 26 at 18:46


















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%2f505679%2fcreating-a-for-loop-with-find-exec-and-while%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

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?