bug-bash
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]