[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help with script.
From: |
Afflictedd2 |
Subject: |
Re: Help with script. |
Date: |
Wed, 19 May 2010 08:16:20 -0700 (PDT) |
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
> <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).
>
>
>
--
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.