Bash Shell syntax error done < $vid' - linux

i have a error
test: line 16: syntax error near unexpected token `done'
test: line 16: ` done < $vid'
my code test
read -p "entrer Liens Video ou le nom d'un fichier contenant des liens:" vid
#Download Video
if [[ -e $vid ]] ; then
while read line
do
python vid-xml-decoder/ultimate.py $line
find . -name "*.flv" | while read line
do
name="$(basename "${line}" .flv)"
#Variable de déplacement de fichier
repExport="./export/"
#mux des fichier
ffmpeg -i "${name}.flv" -vcodec copy -acodec copy mkvtemp.mkv
mkvmerge -v -o "${repExport}${name}.mkv" --default-track 0 --language 0:fre "${name}.ass" mkvtemp.mkv && \
done < $vid
else
python vid-xml-decoder/ultimate.py $vid
# rest of video processing steps
find . -name "*.flv" | while read line
do
name="$(basename "${line}" .flv)"
#Variable de déplacement de fichier
repExport="./export/"
#mux des fichier
ffmpeg -i "${name}.flv" -vcodec copy -acodec copy mkvtemp.mkv
mkvmerge -v -o "${repExport}${name}.mkv" --default-track 0 --language 0:fre "${name}.ass" mkvtemp.mkv && \
fi
in my script I want to offer two possible entering the links manually or with the text file in the same code
exemple
www.website.me/348744jnm
www.website.me/43545ljkjjk
www.website.me/554erer5cf
I have 3 links in my text file and the script will download then mux switch to another mux download links etc
Note: The script must accept space and special character
if you want more information please do not hesitate :)
tx for your help

The error source:
mkvmerge -v -o ..... nguage 0:fre "${name}.ass" mkvtemp.mkv && \
# HERE -------------------------------------------------> ^^
# probably missing one line before "done"
done < $vid
Comments:
easier to debug and maintenace if you start using functions. Break your code to more maintenable parts... You can do anything with functinos as with external commands, like: funcname | while read .. or redirect its output like funcname > somehere and so on..
double quote variables

Related

Sed command not working based on variable

I am having problems in execution a sepefic sed command.
I have a bunch of files which will be target to several "find and replace" via sed.
In the file_test there is the following text example:
*FILENAME TESTE "DIR1.PGM1";*
My desired output is:
*FILENAME TESTE "/NEW_ROOT/DIR1.PGM1";*
The following command works:
*sed -i -e '/FILENAME/s!"!"/NEW_ROOT/!' file_test*
However having several alterations to make I opted to list the on a file a loop through it.
list_changes
FILENAME /NEW_ROOT/
Below its the logic I've implemented:
*#!/bin/bash
diretoria=pasta_b
ficheiro=teste
arquivo_2="$2" # serve para guardar o nome do txt
while read -r linha; do
grep_input=$(echo "$linha" | cut -d " " -f 1) #get input for sed
grep_output=$(echo "$linha" | cut -d " " -f 2) #get output for sed
cd ~/Desktop/FUENTES/"$diretoria"
novo_fich="novo_$ficheiro" #rename file
cat "$ficheiro" >> "$novo_fich".txt #rename file
comand_sed="sed -i -e '/"$grep_input'/s!"!"/'$grep_output"/!' "$novo_fich".txt"
echo "Comando : $comand_sed"
call_comand=$(${comand_sed})
cd ~/Desktop/FUENTES/
done < "$arquivo_2"*
The error it gives is the following:
sed: -e expression #1, char 1: unknown command: `''
However the command_sed variable outputs to a well constructed sed command:
sed -i -e '/LIBNAME/s!"!"/2sasdata2/!' novo_base08.txt
To sum up, my issue is giving a command based on a previously assigned variable (comand_sed)

Using "for" to align paired end sequences

I have a folder with many paired end files (1.1.fq 1.2.fq 2.1.fq 2.2.fq ...) I want to use the "for" to do the aligment for each pair (*.1fq *2.fq) and generate 2 outputs *.stats.txt and *.sam.
I wrote the following command:
for x in *.fq ; do
~/Pedro_Dias/Mamão/Single_end/novocraft/novoalign -d cpapaya.novoIndex -f demultiplex-fq/$x *.1.fq demultiplex-fq/$x *.2.fq -x 3 -H -a -o SAM 2> demultiplex-sam/$x *.stats.txt > demultiplex-sam/$x *.sam;
done
The code return the error:
demultiplex-sam/demultiplex-fq/98.1.fq*.stats.txt:No file or directory
P.s. My files were in demultiplex-fq folder and the output must go to the demultiplex-sam folder. I'm working in a folder that contains the demultiplex-fq demultiplex-sam folders.
You should just loop over one file in the pairs. Then replace .1.fq with .2.fq to get the other file in that pair.
The wildcards need to include the directory name, and then you have to replace the directory when generating the output filenames.
for x in demultiplex-fq/*.1.fq
do
y=${x/.1.fq/.2.fq}
stats=${x/demultiplex-fq/demultiplex/sam}.stats.txt
sam=${x/demultiplex-fq/demultiplex/sam}.sam
~/Pedro_Dias/Mamão/Single_end/novocraft/novoalign -d cpapaya.novoIndex -f "$x" "$y" -x 3 -H -a -o SAM 2> "$stats" > "$sam"
You don't use wildcards in the command, you just use the $x and $y variables.
I used that code and works:
for x in $( ls -1 dem*/*.fq | rev | cut -d . -f 3- | rev | sort -u ) ; do ~/Pedro_Dias/Mamão/Single_end/novocraft/novoalign -d cpapaya.novoIndex -f $x.1.fq $x.2.fq -x 3 -H -a -o SAM 2> ./bams/$(echo $x | tr / _).stats.txtx > ./bams/$(echo $x | tr / _).sam; done

Linux: append all filenames in path to text file

I want to add the filenames of all files of a certain type (*.cub) in the path to a text file in the same path. This file will become the batch (.submit) file. That I can run overnight. I also need to adapt the name a bit.
I do not really know how to describe it better, so I'll give an example:
Let's say I have three files: 001.cub, 002.cub & 003.cub
Then the final text file must be:
[program] -i 001.cub -o 001.vdb
[program] -i 002.cub -o 002.vdb
[program] -i 003.cub -o 003.vdb
It seems a fairly easy operation, but I simply can't get it right.
Also, it really has to become a .submit (or at least some text) file. I cannot run the program immediately.
I hope someone can help!
A simple for loop will do the job:
for i in *.cub
b=$(basename "$i" .cub)
echo "program -i \"$b.cub\" -o \"$b.vdb\""
done >output.txt
Create an empty sh file
List the files *.cub and loop through them
Store the sequence by splitting on dot [.]
echo the required string and append to the sh file of step 1
echo -n "" > 'Run.sh'
for filename in `ls *.cub`
do
sequence=`echo $filename | cut -d "." -f1`
echo "Program -i $filename -o $sequence.vdb" >> Run.sh
done
Directly put the stream into the file as below:
for filename in `ls *.cub`
do
sequence=`echo $filename | cut -d "." -f1`
echo "Program -i $filename -o $sequence.vdb"
done > Run.sh
For everything before the extension to be retained in the variable:
for filename in `ls *.cub`
do
sequence=`echo $filename | rev | cut -d "." -f2- | rev`
echo "Program -i $filename -o $sequence.vdb"
done > Run.sh
For extracting only the numbers from the filename and use accordingly:
for filename in `ls *.cub`
do
sequence=`echo $filename | sed 's/[^0-9]*//g'`
echo "Program -i $filename -o $sequence.vdb"
done > Run.sh
This oneliner will do what you want:
ls *.cub | sort | awk '{split($1,x,"."); print "[program] -i "$1" -o "x[1]".vdb "}' > something.sh

function in loop corrupts every other iteration

I made a short bash program to download podcasts and retrieve only last 20 seconds.
Strange thing is it fails downloading every other iteration. There seems to be a problem with the function trim_nsec, because when I get rid of it in the loop, all the rest correctly works.
Edit : addition of double quotes, which doesn't solve the problem
<!-- language: lang-bash -->
#!/bin/bash
# Get podcast list
wget -O feed http://www.rtl.fr/podcast/on-n-est-pas-forcement-d-accord.xml
function trim_nsec () {
# arguments : 1 : mp3file - 2 : duration - 3 : outputfile
duration=$(ffprobe -i "${1}" -show_entries format=duration -v quiet -of csv="p=0")
nth_second=$(echo "${duration} - ${2}"|bc)
ffmpeg -i "${1}" -ss "${nth_second}" "${3}"
}
cpt=1
# let's work only on the 4th first files
grep -Po 'http[^<]*.mp3' feed|grep admedia| head -n 4 > list
cat list | while read i
do
year=$(echo "$i" | cut -d"/" -f6)
day=$(echo "$i" | cut -d"/" -f7)
fullname=$(echo "$i" | awk -F"/" '{print $NF}')
fullnameend=$(echo "$fullname" |sed -e 's/\.mp3$/_end\.mp3/')
new_name=$(echo "$year"_"$day"_"$fullnameend")
# let's download
wget -O "$fullname" "$i"
# let's trim last 20 sec
trim_nsec "$fullname" 20 "$new_name"
echo "$cpt file processed"
#delete orig. file :
rm "$fullname"
((cpt++))
done
Any idea ?
The problem is most likely due to the fact that on errors, ffmpeg will try to get an input from user which will consume the input provided by cat list. See a similar question here or here. To prevent trim_nsec from consuming the input from cat list, you could do:
cat list | while read i
do
year=$(echo "$i" | cut -d"/" -f6)
day=$(echo "$i" | cut -d"/" -f7)
fullname=$(echo "$i" | awk -F"/" '{print $NF}')
fullnameend=$(echo "$fullname" |sed -e 's/\.mp3$/_end\.mp3/')
new_name=$(echo "$year"_"$day"_"$fullnameend")
# let's download
wget -c -O "$fullname" "$i"
# let's trim last 20 sec
trim_nsec "$fullname" 20 "$new_name" <&3
echo "$cpt file processed"
#delete orig. file :
#rm "$fullname"
((cpt++))
done 3<&1

ffmpeg not working in script - moov atom not found

I made a simple script that divides a flv file into multiple parts, converts them all to .mp4 individually and then merge all of them to form a final mp4 file. I did this to save time and convert large files in parallel.
However, I am stuck because the command that normally runs on command line for ffmpeg, doesn't run via script.
I am kind of stuck here and will like to have some assistance.
#!/bin/bash
#sleep 5
filenametmp=$1;
filename=`echo "$filenametmp" | awk '{split($0,a,"."); print a[1]}'`
echo $filename
output="$filename-output"
filenamewithoutpath=`echo "$output" | awk '{split($0,a,"/"); print a[4]}'`
echo $output $filenamewithoutpath
/usr/bin/ffmpeg -i $filenametmp -c copy -map 0 -segment_time $2 -f segment $output%01d.flv
#sleep 10
#echo "/bin/ls -lrt /root/storage/ | /bin/grep $filenamewithoutpath | /usr/bin/wc -l"
filecounttmp=`/bin/ls -lrt /opt/storage/ | /bin/grep $filenamewithoutpath | /usr/bin/wc -l`
filecount=`expr $filecounttmp - 1`
echo $filecount
for i in `seq 0 $filecount`
do
suffix=`expr 0000 + $i`
filenametoconvert="$output$suffix.flv"
convertedfilename="$output$suffix.mp4"
echo $filenametoconvert
/usr/bin/ffmpeg -i $filenametoconvert -c:v libx264 -crf 23 -preset medium -vsync 1 -r 25 -c:a aac -strict -2 -b:a 64k -ar 44100 -ac 1 $convertedfilename > /dev/null 2>&1 &
done
sleep 5
concatstring=""
for j in `seq 0 $filecount`
do
suffix=`expr 0000 + $j`
convertedfilenamemp4="$output$suffix.mp4"
#concatstring=`concat:$concatstring|$convertedfilenamemp4`
echo "file" $convertedfilenamemp4 >> $filename.txt
#ffmpeg -i concat:"$concatstring" -codec copy $filename.mp4
#ffmpeg -f concat -i $filename.txt -c copy $filename.mp4
done
echo $concatstring
ffmpeg -f concat -i $filename.txt -c copy $filename.mp4
rm $output*
rm $filename.txt
I run any flv file like this :
./ff.sh /opt/storage/tttttssssssssss_573f5b1cd473202daf2bf694.flv 20
I get this error message :
moov atom not found
I am on Ubuntu 14.04 LTS version, standard installation of ffmpeg.

Resources