Back to oliverwolfson.com
Use the following shell script to extract
raw key frame data from After Effects formatted key fame data files, so that
Maya can use it.
The script:
#!/bin/sh
theFile="$1"
newFile=`basename -s ".txt" $theFile`.extracted.txt
theDir=`dirname $theFile`
cat "$theFile" | tr '\r' '\n' \
| grep -n -e "" \
| grep -v -e ^1: -e ^2: \
-e ^3: -e ^4: -e ^5: \
-e ^6: -e ^7: -e ^8: \
-e ^9: -e ^10: -e ^11: \
-e ^12: -e ^13: -e ^14: \
-e End -e "^$" \
| awk -F ":" '{print $2}' \
| awk '{print $2}' \
| grep -v "^$" > "$theDir/$newFile"
exit 0
You can copy After Effects keyframes from
the timeline, and paste them into a text file. The data will look something
like this:
--
Adobe After Effects 8.0 Keyframe Data
Units Per Second 29.97
Source Width 900
Source Height 506
Source Pixel Aspect Ratio 1
Comp Pixel Aspect Ratio 1
Effects Sound Keys #1 Output 1 #22
Frame
1 0.000261479
2 0.00608461
3 0.0153011
4 0.0274689
5 0.0395869
6 0.0493024
7 0.0562797
8 0.0557284
9 0.0997545
10 0.103466
End of Keyframe Data
--
The script will produce something like
this:
--
0.000261479
0.00608461
0.0153011
0.0274689
0.0395869
0.0493024
0.0562797
0.0557284
0.0997545
0.103466
--
The Script commented:
#!/bin/sh
# $1 is the first argument, meaning the first argument used when executing the script: scriptName.sh firstArgument.
# This argument should be a file containing After Effects keyframe data.
# So to execute this script you would write AfterEffectsExtract.sh /path/to/file/myAeKeyframeData.txt
# theFile is a variable holding that first argument.
# Using this variable in the script makes it somewhat more human readable.
theFile="$1"
# newFile is a variable which holds the name of the new file we are creating.
# `basename -s ".txt" $theFile` gets the name of theFile and strips off the ".txt" extension.
# .extracted.txt is added to the end of the name, creating a unique name for the new file.
newFile=`basename -s ".txt" $theFile`.extracted.txt
# theDir is a variable which holds the path to the directory we are working in.
theDir=`dirname $theFile`
# cat "prints" the contents of theFile, that is, it delivers it via pipe, |, to the tr command.
# the tr command is a search and replace command.
# Here it is set up to replace all Mac style line returns "\r" with Unix style line returns "\n".
# The \ creates a line return, visually so we can read this code, but does not interrupt the code.
cat "$theFile" | tr '\r' '\n' \
# grep -n -e "" adds line numbers, a numeral and a colon (1:, 2: , 3:, etc) to each line of data.
# -e = pattern, -n = line number, "" = all
# see ** below to see what the data looks like after running this grep command!
| grep -n -e "" \
# grep will return matching lines
# grep -v will invert, return lines not matching the arguments
# -e = pattern, ^ = starts with
# we list the lines we don't want to include: lines that start with 1:, 2:, 3:, etc.
# also excluded are lines that include the word "End" and any blank lines (-e "^$", ^ = starts with, $ = ends with, "nothing")
| grep -v -e ^1: -e ^2: \
-e ^3: -e ^4: -e ^5: \
-e ^6: -e ^7: -e ^8: \
-e ^9: -e ^10: -e ^11: \
-e ^12: -e ^13: -e ^14: \
-e End -e "^$" \
# with awk, we can edit the lines. We can remove part of the lines up to and including a delimiter.
# The -F option defines the input field separator to be the regular expression.
# the delimiter, or input field separator, is ":"
# {print $2} prints $2, the second column.
# so in fact we could just write awk '{print $2}', that would give us the same result.
# yes this part is redundant ;), but it still works.
| awk -F ":" '{print $2}' \
| awk '{print $2}' \
# grep -v "^$" makes certain that there are no remaining blank lines. Redundant, maybe, again, it works..
# > "$theDir/$newFile" writes newFile to theDir directory.
| grep -v "^$" > "$theDir/$newFile"
# exit(0) is a shell built-in command that causes program termination.
# The exit statement will exit the current shell script.
# It can be given a numeric argument which is the script's exit status.
# If omitted the exit status of the last run command is used.
# 0 (zero) signifies success, non-zero signifies failure.
exit 0
--
** The data will look something like this, below, after we run grep –n –e рс
1:Adobe After Effects 8.0 Keyframe Data
2:
3: Units Per Second 29.97
4: Source Width 900
5: Source Height 506
6: Source Pixel Aspect Ratio 1
7: Comp Pixel Aspect Ratio 1
8:
9:Effects Sound Keys #1 Output 1 #22
10: Frame
11: 874 22.9339
12: 875 22.0806
13: 876 12.0954
Detailed explanation of
AfterEffectsKeyExtract.sh by Jeshua Lacock OpenOSX.com
this line:
theFile="$1"
sets the variable theFile to the first argument
(which is the file name)
it is an argument variable
we could just use it directly, but it makes it more clear if we label it
this line:
newFile=`basename -s ".txt" $1`.key
makesit remove .txt and append .key
so this line:
newFile=`basename -s ".txt" $theFile`.extracted.txt
sets a newFile variable to be the file name minus .txt plus .extracted.txt
cat "$theFile"
just prints the file to the screen which is piped to tr
tr '\r' '\n'
changes it from Mac to Unix line returns
which pipes it to grep
grep -n -e ""
grep is like a find for individual lines
numbers the lines with the -n option, and -e is what we want to match - everything in this case
-n is the number of lines/
By default, grep prints the matching lines.
that is the option to print the line number
so all we are doing so far is printing all of the lines with the line number for each line first
so the lines look like this at this point:
1:Adobe After Effects 8.0 Keyframe Data
2:
3: Units Per Second 29.97
4: Source Width 900
5: Source Height 506
6: Source Pixel Aspect Ratio 1
7: Comp Pixel Aspect Ratio 1
8:
9:Effects Sound Keys #1 Output 1 #22
10: Frame
11: 874 22.9339
12: 875 22.0806
13: 876 12.0954
next is a long grep line, starting with:
grep -v -e ^1:
grep -v is the opposite of grep - it print everything *but* the matching lines
^1: means match a line that starts with 1:
so you list the line u dont want
so the -v makes it not print that line
up to 14
because we don't want the first 14 lines
we also want to ignore lines that say the word "End" with:
-e End
and we want to ignore blank lines with:
-e "^$"
so at this point it looks like:
11: 874 22.9339
12: 875 22.0806
13: 876 12.0954
14: 877 7.173
15: 878 5.63299
16: 879 7.08297
17: 880 9.63439
18: 881 10.511
19: 882 10.6646
20: 883 9.12829
next, we pipe it to awk
| awk -F ":" '{print $2}'
with -F we are specifying the delimiter
which is :
and saying we want the 2nd field
'{print $2}'
so 11: 874 22.9339 becomes 874 22.9339
so unix sees each block of text as a "feild"?
field
it sees the fields based on the -F
which is :
by default it is any blank space
(space tab, etc)
then we send it awk that uses the space as the delimiter:
| awk '{print $2}'
we don't have to specify the delimiter because it is space by default
note that we actually would only need this
we don't need the first one now that I think about it
okay so the delimiter in the first case is :
anways, that makes 874 22.9339 become 22.9339
in the second case is a space
yeah - and we could go straight from 11: 874 22.9339 to 22.9339 by using the space only
I used : because the first thing I wanted to get rid of is the line numbers
awk = pattern-directed scanning and processing language
:-&
have no idea why awk though
then it pipes it grep:
grep -v "^$"
which ignores any blank lines (again)
> "$newFile" sends the whole stream out to our new file variable
thats it