Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
i started trying to write a script to batch encode files into ffmpeg. failed miserably, then found tovid and don't really need it anymore. still, i was curious. my problem was that i couldn't find a way to select all files in a directory, perform a command on each, and output each file discreetly. i think the latter problem can be solved with "basename". ideas that failed:
1. since the files were named "1x0[1-23] something.avi", i tried to figure a way to set an input variable as the fourth character, then increment the variable up on the next pass. eg, INPUT=1, then first file name would be "1x0[$INPUT]*.avi". i couldn't figure out how to expand the wildcard though.
2. try to print the filenames directly to the variable. i tried various ways of doing this, but couldn't figure out how to pipe the output of something into a variable.
3. a variation on #1: i was able to get to
#!/bin/bash
for i in `ls *.avi`
do
FILE="basename $i"
ffmpeg -i $FILE -sameq -target ntsc -vcd $FILE.mpg
done
cd to the directory containing the .avi files to run the script. `ls *.avi` runs ls and lists the .avi files. Each iteration of the loop sets File equal to the basename of the file listed in that iteration.
Using variable substitution, you can extract certain characters from the variable containing the filename, and use that in your script.
For example, if $input is assigned in a for loop like, "for input in 1x[[:digit:]][[:digit:]]*.avi; do"
and lets say a filename "1x01elephant.avi" is assigned to $input. Then ${input:2:2} will select the 3rd and 4th characters in the variable. Another one that might be useful is ${input#1x[[:digit:]][[:digit:]]} which will strip off the 1x[[:digit:]][[:digit:]] part, leaving only "elephant.avi".
You can enter the output of a command used in a command using either backticks or $(command ... ).
The latter is recommended. It has the advantage where one could be embedded inside another.
for basevid in $( 1x[[:digit:]][[:digit:]]*.avi | sed 's/1x..\(.*\).avi/\1/' | sort | uniq ); do
for vid in 1x[[:digit:]][[:digit:]]$basevid; do
...
done
done
This would allow you to process all files 1x??elephant.avi separately from 1x??zebra.avi.
Sometimes, you might want to build up an array:
zoo=( $(ls 1x[[:digit:]][[:digit:]]*.avi | sed 's/1x..\(.*\)/\1 | sort | uniq) )
For 1 and 3, look at above posts. Variables & wildcards are expanded automatically by the shell, unless you put them inside single quotes. Be careful when using a variable as part of a string, like $Y in your example. To make it clear the "Y" is the name of your variable (not $Y*, $Y*avi or something), you should enclose the Y
in curly braces, ie ...${Y}*.avi...
For 2, and this is done implicitly in the for-loop of bigrigdriver's post:
use backticks (``, which are not the same as single quotes '').
or the $(...) operator.
Example:
"echo $myVar" will then show that the variable contains the string "something".
"echo $myVar2" will show that myVar2 holds the string "1x0..something.avi" (so yes, $myVar is expanded by the backticks).
As a general remark, I suggest you read pieces of "man bash". Especially the parts on quoting and variable syntax for starters.
thanks for the help.
timmeke, yes, i had tried all variety of quotes trying to make it work without success.
jschiwal. that all seems a bit above me at this point. not sure what exactly [[:digit:]] does. took a look at sed, which seems pretty complicated.
bigrigdriver, that seems about my speed, but i'm still having troubles. it seems that spaces (and probably other non-standard characters too) aren't being interpreted correctly.
Code:
for i in `ls *.avi`
gives me an output of
Code:
1x01
,
when what i want is:
Code:
1x01 Juliet Prowse.avi
using ls -b, -Q didn't help. each word is interpreted as a separate variable.
and, tovid isn't giving me the results i want, so that's giving me extra incentive to get it done...
By default, the shell (ie in your for-loop) splits the 'ls' output on word boundaries like spaces and tabs.
If you only want to split on newlines, like in your case, just put the following command before the for-loop.
Code:
IFS="\n";
You can check "man bash" for details on the IFS environment variable.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.