Skip to main content
syntax highlighting; spelling
Source Link
David Foerster
  • 36.7k
  • 56
  • 96
  • 149

I'm not sure why you are wrapping this in a shell function - I will assume that's a requirement of your assignment.

First, note that using "*;"* as a field separator in awkAwk is not a robust way to handle quoted CSV fields - it will fail for example if either the first field or last field on a line is quoted, and it won't preserve quoted delimiters (i.e e. quoted fields that actually contain a ;) which misses the whole point of quoting CSV fields.

Second, you should not try to pass shell variables (or positional parameters) into awkAwk expression that way - the correct way is either to export them and then access them via the ENVIRON array, or use command line option -v. So your "single customer" implementation would be better written

delcust() {
  awk -F '"*;"*' -v cust="$1" '$1 != cust' input.csv > output.csv
}
delcust "$1"
delcust() {
  awk -F '"*;"*' -v cust="$1" '$1 != cust' input.csv > output.csv
}
delcust "$1"

While you could modify this to pass multiple positional parameters, I'd suggest passing the customer list via standard input and parsing it as a file of values; that way you can do a canonical awkAwk lookup based on an associative array (or hash):

delcusts() {
  printf '%s\n' "$@" | awk -F'"*;"*' 'NR==FNR {custs[$0]=1; next} !($1 in custs)' - input.csv > output.csv
}
delcusts "$@"
delcusts() {
  printf '%s\n' "$@" | awk -F'"*;"*' 'NR==FNR {custs[$0]=1; next} !($1 in custs)' - input.csv > output.csv
}
delcusts "$@"

Note that you don't need an explicit print in awkAwk since print is the default action if a rule evaluates non-zero.

I'm not sure why you are wrapping this in a shell function - I will assume that's a requirement of your assignment.

First, note that using "*;"* as a field separator in awk is not a robust way to handle quoted CSV fields - it will fail for example if either the first field or last field on a line is quoted, and it won't preserve quoted delimiters (i.e. quoted fields that actually contain a ;) which misses the whole point of quoting CSV fields.

Second, you should not try to pass shell variables (or positional parameters) into awk expression that way - the correct way is either to export them and then access them via the ENVIRON array, or use command line option -v. So your "single customer" implementation would be better written

delcust() {
  awk -F '"*;"*' -v cust="$1" '$1 != cust' input.csv > output.csv
}
delcust "$1"

While you could modify this to pass multiple positional parameters, I'd suggest passing the customer list via standard input and parsing it as a file of values; that way you can do a canonical awk lookup based on an associative array (or hash):

delcusts() {
  printf '%s\n' "$@" | awk -F'"*;"*' 'NR==FNR {custs[$0]=1; next} !($1 in custs)' - input.csv > output.csv
}
delcusts "$@"

Note that you don't need an explicit print in awk since print is the default action if a rule evaluates non-zero.

I'm not sure why you are wrapping this in a shell function - I will assume that's a requirement of your assignment.

First, note that using "*;"* as a field separator in Awk is not a robust way to handle quoted CSV fields - it will fail for example if either the first field or last field on a line is quoted, and it won't preserve quoted delimiters (i. e. quoted fields that actually contain a ;) which misses the whole point of quoting CSV fields.

Second, you should not try to pass shell variables (or positional parameters) into Awk expression that way - the correct way is either to export them and then access them via the ENVIRON array, or use command line option -v. So your "single customer" implementation would be better written

delcust() {
  awk -F '"*;"*' -v cust="$1" '$1 != cust' input.csv > output.csv
}
delcust "$1"

While you could modify this to pass multiple positional parameters, I'd suggest passing the customer list via standard input and parsing it as a file of values; that way you can do a canonical Awk lookup based on an associative array (or hash):

delcusts() {
  printf '%s\n' "$@" | awk -F'"*;"*' 'NR==FNR {custs[$0]=1; next} !($1 in custs)' - input.csv > output.csv
}
delcusts "$@"

Note that you don't need an explicit print in Awk since print is the default action if a rule evaluates non-zero.

Source Link
steeldriver
  • 140.3k
  • 23
  • 252
  • 350

I'm not sure why you are wrapping this in a shell function - I will assume that's a requirement of your assignment.

First, note that using "*;"* as a field separator in awk is not a robust way to handle quoted CSV fields - it will fail for example if either the first field or last field on a line is quoted, and it won't preserve quoted delimiters (i.e. quoted fields that actually contain a ;) which misses the whole point of quoting CSV fields.

Second, you should not try to pass shell variables (or positional parameters) into awk expression that way - the correct way is either to export them and then access them via the ENVIRON array, or use command line option -v. So your "single customer" implementation would be better written

delcust() {
  awk -F '"*;"*' -v cust="$1" '$1 != cust' input.csv > output.csv
}
delcust "$1"

While you could modify this to pass multiple positional parameters, I'd suggest passing the customer list via standard input and parsing it as a file of values; that way you can do a canonical awk lookup based on an associative array (or hash):

delcusts() {
  printf '%s\n' "$@" | awk -F'"*;"*' 'NR==FNR {custs[$0]=1; next} !($1 in custs)' - input.csv > output.csv
}
delcusts "$@"

Note that you don't need an explicit print in awk since print is the default action if a rule evaluates non-zero.