사용자 입력을 대체하기 위해 기존 루프 주위에 for 루프를 구축합니다.

사용자 입력을 대체하기 위해 기존 루프 주위에 for 루프를 구축합니다.

기본적으로 다음 스크립트가 있습니다.

#!/bin/bash

#Asks For filname and Word
echo 'Which word are you looking for?'
read word
echo 'What's the name of the file?'
read fileName


#Searches word and parses the line-numbers 
wordOut=$(grep -i -n -w $word $fileName.srt |cut -f1 -d:)

#Sets all outputs to diffrent line numbers and saves a temp file
for word in $wordOut
do
    echo $word
done >file.tmp

#Parses lines to array, removes temp file
mapfile -t arr <file.tmp
rm file.tmp

#Declares variable for the number of array entries (not used anywhere atm)
ln=${#arr[@]}

#Subtract all array entries with one
one=1
for i in "${arr[@]}"
do
    crc=`expr $i - $one`
    echo $crc
done >two.tmp

#Subtraction result to array2
mapfile -t arr2 <two.tmp
rm two.tmp
echo ${arr2[@]}

#retrieve times
for h in "${arr2[@]}"
do 
    line=$(sed "${h}q;d" $fileName.srt)
    echo $line
done >three.tmp

#replace all commas with decimal points
sed 's/,/./g' three.tmp >four.tmp

#remove temp file 3 and parse 'decimal pointed' to array
rm three.tmp
mapfile -t arr3 <four.tmp
rm four.tmp

echo ${arr3[0]}
echo ${arr3[1]}

# converts HH:MM:SS.sss to fractional seconds
codes2seconds() (
  local hh=${1%%:*}
  local rest=${1#*:}
  local mm=${rest%%:*}
  local ss=${rest#*:}
  printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss")
)

# converts fractional seconds to HH:MM:SS.sss
seconds2codes() (
  local seconds=$1
  local hh=$(bc <<< "scale=0; $seconds / 3600")
  local remainder=$(bc <<< "$seconds % 3600")
  local mm=$(bc <<< "scale=0; $remainder / 60")
  local ss=$(bc <<< "$remainder % 60")
  printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss"
)

subtracttimes() (
  local t1sec=$(codes2seconds "$1")
  local t2sec=$(codes2seconds "$2")
  printf "%s" $(bc <<< "$t2sec - $t1sec")
)


for range in "${arr3[@]}"
do  
  mod=$(sed 's/[^0-9]//g' <<< $range)
  duration=$(subtracttimes "${range%% -->*}" "${range##*--> }")
  printf "%s\n" "ffmpeg -i $fileName.mp4 -ss ${range%% -->*} -t $duration -async 1 $word.$mod.$fileName.cut.mp4"


done >final.tmp
sudo chmod 755 final.tmp
./final.tmp
rm final.tmp

효과는 매우 좋습니다. 기능: mp4 파일과 이름이 같은 srt 파일에서 키워드를 검색하고, 키워드와 일치하는 타임스탬프를 찾아 시작 지점부터 끝 지점까지 영상을 잘라냅니다.

SRT 파일 예:

**video.srt**
1
00:00:00,000 --> 00:00:04,950
welkom bij eerste toekomst reizen dus

2
00:00:02,639 --> 00:00:05,670
onderdeel aan de achterhoekse toekomst

3
00:00:04,950 --> 00:00:07,290
stoere

4
00:00:05,670 --> 00:00:11,250
mijn heren nu al heel veel dingen

따라서 기본적으로 "toekomst"라는 키워드를 찾고 있다면 두 개의 mp4가 출력됩니다. 하나는 처음에 로 시작 00:00:00,000하고 끝나며 00:00:04,950, 다른 하나는 로 시작 00:00:02,639하고 끝납니다 00:00:05,670.

동일한 디렉터리에 여러 개의 MP4가 있고, 모두 mp4와 동일한 이름을 가진 해당 .srt 파일이 있으며, 이러한 파일은 모두 이 스크립트를 통해 실행되어야 합니다. 그래서 이름이 같은 모든 파일을 찾아 스크립트를 통해 실행하는 스크립트 확장을 만들고 싶습니다.

그래서 테스트하기 위해 다음 코드를 작성했습니다.

#!/bin/bash
cd "`dirname "$0"`"
for file in *.srt
do 
fileName="$( basename "$file" .srt)"
echo $fileName
echo $fileName.mp4
echo $fileName.srt

done >temp

디렉터리에 있는 모든 .mp4 파일과 .srt 파일의 출력을 제공합니다.

h
h.mp4
h.srt
r
r.mp4
r.srt

그런 다음 다음과 같이 기존 코드 주위에 for 루프를 만들었습니다.

#!/bin/bash
cd "`dirname "$0"`"
#Asks For filname and Word
echo 'Which word are you looking for?'
read word

for file in *.srt
do 
fileName="$( basename "$file" .srt)"

#Searches word and parses the line-numbers 
wordOut=$(grep -i -n -w $word $fileName.srt |cut -f1 -d:)

#Sets all outputs to diffrent line numbers and saves a temp file
for word in $wordOut
do
    echo $word
done >file.tmp

#Parses lines to array, removes temp file
mapfile -t arr <file.tmp
rm file.tmp

#Declares variable for the number of array entries (not used anywhere atm)
ln=${#arr[@]}

#Subtract all array entries with one
one=1
for i in "${arr[@]}"
do
    crc=`expr $i - $one`
    echo $crc
done >two.tmp

#Subtraction result to array2
mapfile -t arr2 <two.tmp
rm two.tmp
echo ${arr2[@]}

#retrieve times
for h in "${arr2[@]}"
do 
    line=$(sed "${h}q;d" $fileName.srt)
    echo $line
done >three.tmp

#replace all commas with decimal points
sed 's/,/./g' three.tmp >four.tmp

#remove temp file 3 and parse 'decimal pointed' to array
rm three.tmp
mapfile -t arr3 <four.tmp
rm four.tmp

echo ${arr3[0]}
echo ${arr3[1]}

# converts HH:MM:SS.sss to fractional seconds
codes2seconds() (
  local hh=${1%%:*}
  local rest=${1#*:}
  local mm=${rest%%:*}
  local ss=${rest#*:}
  printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss")
)

# converts fractional seconds to HH:MM:SS.sss
seconds2codes() (
  local seconds=$1
  local hh=$(bc <<< "scale=0; $seconds / 3600")
  local remainder=$(bc <<< "$seconds % 3600")
  local mm=$(bc <<< "scale=0; $remainder / 60")
  local ss=$(bc <<< "$remainder % 60")
  printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss"
)

subtracttimes() (
  local t1sec=$(codes2seconds "$1")
  local t2sec=$(codes2seconds "$2")
  printf "%s" $(bc <<< "$t2sec - $t1sec")
)


for range in "${arr3[@]}"
do  
  mod=$(sed 's/[^0-9]//g' <<< $range)
  duration=$(subtracttimes "${range%% -->*}" "${range##*--> }")
  printf "%s\n" "ffmpeg -i $fileName.mp4 -ss ${range%% -->*} -t $duration -async 1 $word.$mod.$fileName.cut.mp4"


done >final.tmp
sudo chmod 755 final.tmp
./final.tmp
rm final.tmp

done

첫 번째 실행의 경우 첫 번째 파일은 올바른 출력 mp4를 제공하지만 올바른 출력을 얻지 못하게 하는 방식으로 변수를 섞습니다.

답변1

다른 스크립트를 사용하고 변수를 기본 스크립트로 내보내서 직접 수정했기 때문에 결국 두 스크립트를 모두 사용하게 되었습니다. 주요 스크립트:

#!/bin/bash
echo 'Welk woord zoek je?'
read word
export word

for file in *.srt
do

fileName="$( basename "$file" .srt)"
export fileName
./actualScript

done

실제 스크립트:

#!/bin/bash
#Asks For filname and Word

#Searches word and parses the line-numbers 
wordOut=$(grep -i -n -w $word $fileName.srt |cut -f1 -d:)

#Sets all outputs to diffrent line numbers and saves a temp file
for word in $wordOut
do
    echo $word
done >file.tmp

#Parses lines to array, removes temp file
mapfile -t arr <file.tmp
rm file.tmp

#Declares variable for the number of array entries (not used anywhere atm)
ln=${#arr[@]}

#Subtract all array entries with one
one=1
for i in "${arr[@]}"
do
    crc=`expr $i - $one`
    echo $crc
done >two.tmp

#Subtraction result to array2
mapfile -t arr2 <two.tmp
rm two.tmp
echo ${arr2[@]}

#retrieve times
for h in "${arr2[@]}"
do 
    line=$(sed "${h}q;d" $fileName.srt)
    echo $line
done >three.tmp

#replace all commas with decimal points
sed 's/,/./g' three.tmp >four.tmp

#remove temp file 3 and parse 'decimal pointed' to array
rm three.tmp
mapfile -t arr3 <four.tmp
rm four.tmp

echo ${arr3[0]}
echo ${arr3[1]}

# converts HH:MM:SS.sss to fractional seconds
codes2seconds() (
  local hh=${1%%:*}
  local rest=${1#*:}
  local mm=${rest%%:*}
  local ss=${rest#*:}
  printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss")
)

# converts fractional seconds to HH:MM:SS.sss
seconds2codes() (
  local seconds=$1
  local hh=$(bc <<< "scale=0; $seconds / 3600")
  local remainder=$(bc <<< "$seconds % 3600")
  local mm=$(bc <<< "scale=0; $remainder / 60")
  local ss=$(bc <<< "$remainder % 60")
  printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss"
)

subtracttimes() (
  local t1sec=$(codes2seconds "$1")
  local t2sec=$(codes2seconds "$2")
  printf "%s" $(bc <<< "$t2sec - $t1sec")
)


for range in "${arr3[@]}"
do  
  mod=$(sed 's/[^0-9]//g' <<< $range)
  duration=$(subtracttimes "${range%% -->*}" "${range##*--> }")
  printf "%s\n" "ffmpeg -i $fileName.mp4 -ss ${range%% -->*} -t $duration -async 1 $word.$mod.$fileName.cut.mp4"


done >final.tmp
sudo chmod 755 final.tmp
./final.tmp
rm final.tmp

관련 정보