[opensuse] bash: how to get file extension
Hi everyone How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4" I've tried these: ext=${video_title/*./} ext=${FILENAME##*.} ext=$(echo "$video_title" | sed 's/^.*\.//') The problem is the .'s I want to ignore all .'s until the final one (not just for this string). Thanks, L x -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Mon, 2013-07-15 at 11:01 +0200, lynn wrote:
Hi everyone How do I get the mp4 from this? ** video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
I've tried these:
ext=${video_title/*./} ext=${FILENAME##*.} ext=$(echo "$video_title" | sed 's/^.*\.//')
The problem is the .'s
I want to ignore all .'s until the final one (not just for this string).
Thanks, L x
** Sorry. Should be: video_title= and ext=${video_title##*.} -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Monday 15 Jul 2013 11:05:39 lynn wrote:
On Mon, 2013-07-15 at 11:01 +0200, lynn wrote:
Hi everyone How do I get the mp4 from this?
**
video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
Scan backwards from the end until you get a "." ?
I've tried these:
ext=${video_title/*./} ext=${FILENAME##*.} ext=$(echo "$video_title" | sed 's/^.*\.//')
The problem is the .'s
I want to ignore all .'s until the final one (not just for this string).
Thanks, L x
** Sorry. Should be: video_title= and ext=${video_title##*.} -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Friday, 2013-07-19 at 17:02 +0100, ianseeks wrote:
Scan backwards from the end until you get a "." ?
Yes, that's how i would do it if i were to code it from scratch. But here we try to do it from programs and primitives ready done and usable from bash. - -- Cheers, Carlos E. R. (from 12.3 x86_64 "Dartmouth" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEARECAAYFAlHpnjAACgkQtTMYHG2NR9W+4gCeOexVExdd9g6V5RilinNlfKM9 oqoAn15sXE9mmPZxdVVxPKgeT1X4xI61 =XJVn -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday, 2013-07-15 at 11:01 +0200, lynn wrote:
Hi everyone How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
You can use "basename" to get, well, the base name without the rest. Well, the rest is considered the path, because "extensions" do not exist in Linux :-p But it can remove an extension if it is known in advance. And what you want is getting the extension, right? - -- Cheers, Carlos E. R. (from 12.3 x86_64 "Dartmouth" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEARECAAYFAlHjvxYACgkQtTMYHG2NR9V3ZgCeNicFGS43q4CTb/65ihb0HDZs B3MAmwW6IlBHLqTCa+avUj3rfTQxdoSk =Nc9S -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday, 2013-07-15 at 11:21 +0200, Carlos E. R. wrote:
On Monday, 2013-07-15 at 11:01 +0200, lynn wrote:
But it can remove an extension if it is known in advance. And what you want is getting the extension, right?
I found this: # (from /usr/local/bin/rosegarden-audiofile-importer) base=`basename "$infile"` stem=${base%.*} extension=${base##*.} extension=`echo $extension | tr '[A-Z]' '[a-z]'` I have not tested it. - -- Cheers, Carlos E. R. (from 12.3 x86_64 "Dartmouth" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEARECAAYFAlHjwSoACgkQtTMYHG2NR9VABQCfaMVQUnuNXQaYH4XfL+bCeLWq 0qQAmQGCJrFEppzziWWEmMoulmrpuBfT =eRP3 -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Hello, On Mon, 15 Jul 2013, Carlos E. R. wrote:
I found this:
# (from /usr/local/bin/rosegarden-audiofile-importer)
base=`basename "$infile"`
*tsk* ;)
stem=${base%.*} extension=${base##*.}
For years I have (commented, just to remember) # alias basename='echo ${1##*\/}' # alias dirname='echo ${1%\/*}' in my .bashrc. I.e. the above should be: base="${infile##*\/}" stem="${base%.*}" extension="${base##*.}" The general pattern is: Use "${var##*C}" to get stuff after the last C use "${var#*C}" to get stuff after the first C use "${var%C*}" to get stuff before the last C use "${var%%C*}" to get stuff before the first C HTH, -dnh -- "Amnesia used to be my favorite word, but then I forgot it." -- the BSD fortune file -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Mon, 2013-07-15 at 11:21 +0200, Carlos E. R. wrote:
On Monday, 2013-07-15 at 11:01 +0200, lynn wrote:
Hi everyone How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
You can use "basename" to get, well, the base name without the rest. Well, the rest is considered the path, because "extensions" do not exist in Linux :-p
But it can remove an extension if it is known in advance. And what you want is getting the extension, right?
I want only whatever is after the last . Thanks. I'll have a go with basename but I'd rather do it direct. L x -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
lynn [15.07.2013 11:01]:
Hi everyone How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
I've tried these:
ext=${video_title/*./} ext=${FILENAME##*.} ext=$(echo "$video_title" | sed 's/^.*\.//')
The problem is the .'s
I want to ignore all .'s until the final one (not just for this string).
Thanks, L x
Not nice, but works. On http://tldp.org/LDP/abs/html/string-manipulation.html, I did not find something like strrchr() in C, so I tried to implement it the complicated way: ---snip--- video_id="Robin Thicke - Blurred Lines ft. T.I.,Pharrell-yyDUC1LUXSU.mp4" STRLEN=${#video_id} LOOPI=$((STRLEN-1)) TESTSTR="z${video_id:$LOOPI:1}" while [ "$TESTSTR" != "z." ] ; do TESTSTR="z${video_id:$LOOPI:1}" LOOPI=$((LOOPI-1)) done EXTLEN=$((STRLEN-LOOPI)) FIRSTPART=${video_id:1:$LOOPI} FIRSTLEN=$((${#FIRSTPART}+2)) LASTPART=${video_id:$FIRSTLEN:$EXTLEN} echo "Found first part: $FIRSTPART" echo "Found extension: $LASTPART" ---pins--- Whenever I leave away the "z" in the comparison, I get '"." is a directory'. Hm. HTH, Werner -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 07/15/2013 11:01 AM, lynn wrote:
How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
man bash v="some.file.ext" $ echo "${v%.*}" some.file $ echo "${v%%.*}" some $ echo "${v#*.}" file.ext $ echo "${v##*.}" ext Have a nice day, Berny -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Mon, 2013-07-15 at 11:58 +0200, Bernhard Voelker wrote:
On 07/15/2013 11:01 AM, lynn wrote:
How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
man bash
v="some.file.ext"
$ echo "${v%.*}" some.file
$ echo "${v%%.*}" some
$ echo "${v#*.}" file.ext
$ echo "${v##*.}" ext
Have a nice day, Berny
It's nice and short but it only works if you know the number of .'s:( L x -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 07/15/2013 12:08 PM, lynn wrote:
It's nice and short but it only works if you know the number of .'s:(
Why? "${v%.*}" strips off everything past and including the last dot, while "${v%%.*}" strips off everything past and including the first dot. Likewise, "${v#*.}" returns everything past the first dot, and "${v##*.}" gives everything past the last dot. So in your case - as you want the file extension - the best bet is "${video_id##*.}" which will return "mp4". Have a nice day, Berny -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Bernhard Voelker [15.07.2013 12:36]:
On 07/15/2013 12:08 PM, lynn wrote:
It's nice and short but it only works if you know the number of .'s:(
Why?
"${v%.*}" strips off everything past and including the last dot, while "${v%%.*}" strips off everything past and including the first dot.
Likewise, "${v#*.}" returns everything past the first dot, and "${v##*.}" gives everything past the last dot.
So in your case - as you want the file extension - the best bet is "${video_id##*.}" which will return "mp4".
Yes, it should - but in <1373879139.4191.8.camel@hh16.hh3.site> he wrote that this does not work for him. So I looked for a far more complicated way. Just my 2¢, Werner -- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Mon, 2013-07-15 at 12:36 +0200, Bernhard Voelker wrote:
On 07/15/2013 12:08 PM, lynn wrote:
It's nice and short but it only works if you know the number of .'s:(
Why?
My fault. The string is created in another shell. It works fine on the ground, exactly as in your example. I had to combine the scripts.
"${v##*.}" gives everything past the last dot.
So in your case - as you want the file extension - the best bet is "${video_id##*.}" which will return "mp4".
Works perfectly. Elegant. Thanks -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 7/15/2013 5:01 AM, lynn wrote:
Hi everyone How do I get the mp4 from this? video_id="Robin Thicke - Blurred Lines ft. T.I., Pharrell-yyDUC1LUXSU.mp4"
I've tried these:
ext=${video_title/*./}
ext=${FILENAME##*.}
This is it right here. I assure you. % F=/path/to/foo.blah.txt % echo "${F##*.}" txt
ext=$(echo "$video_title" | sed 's/^.*\.//')
The problem is the .'s
I want to ignore all .'s until the final one (not just for this string).
You are saying you want the final answer to _include_ the dot? That is an unreasonably complicated thing to try to do for not enough gain. It's possible with sed, but you're working too hard to figure out that sed/regex syntax, and by forking a process to run sed, also making the computer work too hard. The simple and practical answer is just to add the dot back in yourself like this: ext=".${FILENAME##*.}" That is not technically truth right there. If the file has no extension then you will get ext="." which basically claims that the original file name ended with a dot, which is not true. But since you are probably just looking for a match from a list of known extensions and they all have a leading dot, this should be fine. Any files that don't have a dot anywhere in the file name, resulting in ext=".", or have a dot somewhere in the middle, resulting in ext=". Strangelove or : How I Learned to Stop Worrying and Love the Bomb" Well those files would have failed to match _anyways_ so it doesn't matter. How to code a particular thing vastly depends on the rest of the job it is a part of. You can make your life unnecessarily hard by trying to get a detail to work a certain way without considering the rest of the context. In this case, I don't think your really need exactly what you asked for and above is good enough, except for two more things: 1 - You probably want to convert ext to all upper or all lower so that you find the matches that YOU and I know are correct even if the computer doesn't. You know that file.Avi is an avi file even though it doesn't match either .avi or .AVI. For that you can typeset ext so it is all up or all low. put this near the top of the script, before ext is ever used. typeset -l ext or typeset -u ext 2 - You probably want to try using file magic (the "file" command) as a fall-back in case $ext was not recognized. Or even other more specialized utilities that use more in-depth knowledge of common media files to identify files by their contents instead of relying on their file names. Take one of your video files and rename it without the extension. now run file "movie title here" If you had trouble just clipping the ext off of a filename then parsing this output in a script is probably right out, but the info is there. -- bkw -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Brian K. White said the following on 07/15/2013 12:00 PM:
% F=/path/to/foo.blah.txt % echo "${F##*.}" txt
and for that matter $ F=/usr/bin/foo.x.y.z.txt $ echo "${F##*.}" txt
You are saying you want the final answer to _include_ the dot? That is an unreasonably complicated thing to try to do for not enough gain. It's possible with sed, but you're working too hard to figure out that sed/regex syntax, and by forking a process to run sed, also making the computer work too hard.
The simple and practical answer is just to add the dot back in yourself like this:
ext=".${FILENAME##*.}"
LOL!
That is not technically truth right there. If the file has no extension then you will get ext="." which basically claims that the original file name ended with a dot, which is not true.
Ah,actually $ F=/usr/bin/fooxyztxt $ echo ."${F##*.}" ./usr/bin/fooxyztxt
But since you are probably just looking for a match from a list of known extensions and they all have a leading dot, this should be fine.
Now the important part, sometimes known as Context is Everything
How to code a particular thing vastly depends on the rest of the job it is a part of. You can make your life unnecessarily hard by trying to get a detail to work a certain way without considering the rest of the context. In this case, I don't think your really need exactly what you asked for and above is good enough, except for two more things:
1 - You probably want to convert ext to all upper or all lower so that you find the matches that YOU and I know are correct even if the computer doesn't. You know that file.Avi is an avi file even though it doesn't match either .avi or .AVI.
For that you can typeset ext so it is all up or all low. put this near the top of the script, before ext is ever used. typeset -l ext or typeset -u ext
2 - You probably want to try using file magic (the "file" command) as a fall-back in case $ext was not recognized. Or even other more specialized utilities that use more in-depth knowledge of common media files to identify files by their contents instead of relying on their file names.
Take one of your video files and rename it without the extension. now run file "movie title here"
If you had trouble just clipping the ext off of a filename then parsing this output in a script is probably right out, but the info is there.
Of course if you have a lot of such files to process then perhaps streaming though sed or awk would be simpler, but as Brian says, it depends on the alrger context. -- How long did the whining go on when KDE2 went on KDE3? The only universal constant is change. If a species can not adapt it goes extinct. That's the law of the universe, adapt or die. -- Billie Walsh, May 18 2013 -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On Mon, 2013-07-15 at 12:27 -0400, Anton Aylward wrote:
Brian K. White said the following on 07/15/2013 12:00 PM:
Now the important part, sometimes known as Context is Everything
Is it?
How to code a particular thing vastly depends on the rest of the job it is a part of.
Perfect. I want to get an mp3 from a movie. So here it is in all its contextual glory: #!/bin/bash address=$1 echo YouTube $address video_id=$(echo $1 | cut -d '=' -f2) youtube-dl $1 echo Downoading: $video_id; video_title="$(youtube-dl --get-title $address)" if [ -z "$video_title" ] then { video_title="no title" echo "cant get song title, using no title" } fi full_name=$(ls "$video_title"*) ext="${full_name##*.}" echo Found "$video_title": Converting to "$video_title.mp3" echo Converting. . . ffmpeg -i "/home/lynn/Desktop/$video_title"-"$video_id"."$ext" "$video_title".wav lame --scale 2 "$video_title".wav "$video_title".mp3 #echo Cleaning up. #rm "$full_name" "$video_title".wav echo Written "$video_title.mp3" But seriously guys. Thanks. This list is the best. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Hello, On Mon, 15 Jul 2013, lynn wrote:
Perfect. I want to get an mp3 from a movie. So here it is in all its contextual glory:
#!/bin/bash address=$1 echo YouTube $address video_id=$(echo $1 | cut -d '=' -f2) youtube-dl $1 echo Downoading: $video_id; video_title="$(youtube-dl --get-title $address)" if [ -z "$video_title" ] then { video_title="no title" echo "cant get song title, using no title" } fi full_name=$(ls "$video_title"*)
You might want to look at clive for this part.
ext="${full_name##*.}" echo Found "$video_title": Converting to "$video_title.mp3" echo Converting. . . ffmpeg -i "/home/lynn/Desktop/$video_title"-"$video_id"."$ext" "$video_title".wav lame --scale 2 "$video_title".wav "$video_title".mp3
ffmpeg should be able to directly convert to mp3. Oh, and also, with clive you can choose the qualitity, a lot of YT content is available as VP8/webm or H264/webm with e.g. OGG Vorbis Audio that you probably would want to extract without reencoding. E.g.: ffmpeg -i "$video_title" -acodec copy -vn "${video_title}.${out_ext}" for out_ext, you'd have to check the audio-codec/format e.g. with mplayer (midentify) or mediainfo (e.g. mediainfo --Inform='Audio;%Format%') and choose a suitable container for that Codec (WAV for RIFF, OGG for Vorbis, etc...). Or you could just convert to mp3, i.e. ffmpeg -i "$video_title" -vn "${video_title}.mp3" That should use libmp3lame to encode to mp3, but you should adjust bitrate settings, default seems to be 64kbit/s or so. HTH, -dnh -- Those who use Word for technical write-ups should be shot. Those who are forced to use it by mandate from $PHB should shoot the PHB. -- Stuart Lamble in asr -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday, 2013-07-15 at 12:00 -0400, Brian K. White wrote:
On 7/15/2013 5:01 AM, lynn wrote:
ext=$(echo "$video_title" | sed 's/^.*\.//')
The problem is the .'s
I want to ignore all .'s until the final one (not just for this string).
You are saying you want the final answer to _include_ the dot? That is an unreasonably complicated thing to try to do for not enough gain. It's possible with sed, but you're working too hard to figure out that sed/regex syntax, and by forking a process to run sed, also making the computer work too hard.
The simple and practical answer is just to add the dot back in yourself like this:
One reason for wanting the dot is that you can reconstruct the entire string by concatenation: "path + name + extension". If the extension is missing, doing "name + dot + extension" would not get the original string. Msdos libraries typically included routines to do all that. Linux aparently not, because extensions have (almost) no meaning. Sometimes I create my own path manipulation binary (in pascal). - -- Cheers, Carlos E. R. (from 12.3 x86_64 "Dartmouth" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEARECAAYFAlHpq/MACgkQtTMYHG2NR9X2bgCfWmYtq8i3mo23JHNzCPwkWEvW ur0AniI0Db3Xy85l6Hysq4Nm9u4Q1ItP =9O/A -----END PGP SIGNATURE----- -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
participants (8)
-
Anton Aylward
-
Bernhard Voelker
-
Brian K. White
-
Carlos E. R.
-
David Haller
-
ianseeks
-
lynn
-
Werner Flamme