On Tue, May 18, 2010 at 10:08:54AM -0700, Afflictedd2 wrote: > > I'm tryin to build a script that will extract columns from a comma > sepparated or x delimited file.
And do what with them? That matters, a lot. > I get the following error: > > Naix:Bash Naix$ ./extractCol.sh , cutDemo.input 3 > awk -F',' '{ print $3 }' < cutDemo.input > awk: '{ > awk: ^ invalid char ''' in expression That's because you put literal single quotes into the argument you're giving to awk -F. You don't want to pass literal single quotes along with the delimiter -- you just want to pass the delimiter itself. > #!/usr/bin/env bash > > DELIMETER="'$1'" > FILE=$2 > COLUMNS="'{ print \$$3 }'" > > echo "awk -F$DELIMETER $COLUMNS < $FILE" > awk -F$DELIMETER $COLUMNS < $FILE You have a serious misunderstanding of how shell quoting works. See <http://mywiki.wooledge.org/Quotes> and <http://mywiki.wooledge.org/BashFAQ/050>. You've placed a literal single quote, then the first positional parameter, then another literal single quote, into the variable DELIMETER (which is also misspelled). Later you're attempting to use that variable, but you did not quote it when you used it, and therefore if $1 contains any whitespace or glob characters, that will break. Here is how you preserve a variable correctly: delim="$1" awk -F"$delim" ... You are attempting to put part of an awk command into a variable called COLUMNS. Now, this is a bad idea for two very different reasons: * The variable COLUMNS already means something else. It's the width of the terminal. (This is why we don't use all-capital-letter variable names!) * As BashFAQ/050 says, putting code into variables is a bad idea. If you really want a layer of indirection (although I don't see why you'd want it for something this simple) then you can isolate bits of code in functions. Don't use variables. Especially if you don't understand how to quote things properly -- but even if you do, it's quite difficult to mangle things just right so that it all works after traversing all the layers. So, if I understand the question correctly, what you want is: * Write a program that takes three arguments. The first argument is a single-character delimiter. The second is a filename. The third is a field number. * Extract the <field>th field from every line of <file> (as delimited by <delimiter>) and write them all to stdout, separated by newlines. In pure bash: while IFS="$1" read -r -a array; do printf "%s\n" "${array[$3 - 1]}" done < "$2" In bash+awk: awk -F"$1" -v field="$3" '{print $field}' "$2" Yes, that's the entire script. Slap a #!/bin/sh at the top and it's done (we're not even using bash features in the second one; although we do in the first one).