Help with script.

2010-05-19 Thread Afflictedd2

Hi eveyrone,

I'm tryin to build a script that will extract columns from a comma
sepparated or x delimited file. This is what I have so far, but it doesn't
work. 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

#!/usr/bin/env bash

DELIMETER="'$1'"
FILE=$2
COLUMNS="'{ print \$$3 }'"

echo "awk -F$DELIMETER $COLUMNS < $FILE"
awk -F$DELIMETER $COLUMNS < $FILE

Any help appreciated.

Ted


-- 
View this message in context: 
http://old.nabble.com/Help-with-script.-tp28598751p28598751.html
Sent from the Gnu - Bash mailing list archive at Nabble.com.




Re: Help with script.

2010-05-19 Thread Greg Wooledge
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
 and
.

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 th field from every line of  (as delimited
   by ) 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).



Re: Help with script.

2010-05-19 Thread Allodoxaphobia
On Tue, 18 May 2010 10:08:54 -0700 (PDT), Afflictedd2 wrote:
>
> I'm tryin to build a script 
>
> Any help appreciated.

   comp.unix.shell



Re: Help with script.

2010-05-19 Thread Afflictedd2

Thanks man, I appreciate your help.


Greg Wooledge wrote:
> 
> 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
>  and
> .
> 
> 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 th field from every line of  (as delimited
>by ) 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).
> 
> 
> 

-- 
View this message in context: 
http://old.nabble.com/Help-with-script.-tp28598751p28609763.html
Sent from the Gnu - Bash mailing list archive at Nabble.com.