How I can use 'grep' command to grab some value from the arguments?

5,678

Solution 1

This doesn't use grep, but as a point of reference, you could use bash's =~ conditional operator to compare the script's first argument with the regular expression class for a name, which is defined by the Bash Reference Manual as:

A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names.

$ cat isvarname
#!/bin/bash
if [ "$#" -ne 1 ]
then
   echo "Usage: $0 a-string"
   exit 1
fi

if [[ "$1" =~ ^[[:alpha:]_][[:alnum:]_]*$ ]]
then
  echo yes
else
  echo no
fi

Solution 2

In bash a valid variable name is made of one or more single-byte characters with the first one being alphabetical or underscore, and the remaining ones if any being alphabetical, 0123456789 or underscore.

For instance Stéphane is a valid variable name only in locales where é is single-byte like in ISO-8859-1 where it's the 0xE9 byte, not in UTF-8 where it's encoded as 0xC3 0xA9.

You could do something like:

#! /usr/bin/env bash
is_single_byte() {
  local length_in_bytes length_in_chars
  length_in_chars=${#1}
  local LC_ALL=C
  length_in_bytes=${#1}
  ((length_in_bytes == length_in_chars))
}

re='^[[:alpha:]_][[:alnum:]_]*$'
for var do
  if is_single_byte "$var" && [[ $var =~ $re ]]; then
    printf '"%s" is a valid variable name\n' "$var"
  else
    printf '"%s" is not a valid variable name\n' "$var"
  fi
done
Share:
5,678

Related videos on Youtube

GideokSeong
Author by

GideokSeong

Updated on September 18, 2022

Comments

  • GideokSeong
    GideokSeong almost 2 years

    Actually, I am doing some assignment by follow:

    1: Write a program called valid that prints "yes" if its argument is a valid shell variable name and "no" otherwise:

    What I am doing is I want to find some value which includes some regular expression, such as [0-9]* by using 'grep' command. But I have no idea how to grab some value including that expression from the argument I input, since 'grep' command is basically to capture some line in the file. Any help will be really appreciated

    • Jeff Schaller
      Jeff Schaller about 6 years
      Do you think they’re expecting a bash script from you? And that the valid variable name is for the bash shell? How much have you learned this far, besides grep? Anything about referring to script parap?
    • GideokSeong
      GideokSeong about 6 years
      Yes, I need to code for a bash script. When script name is 'valid', and I run it as follow: valid 1234 -> it has to print yes or no depending on argument is correct name of variable
    • Angel Todorov
      Angel Todorov about 6 years
      It seems like the piece you're missing is how to get the argument. In bash, they are known as the "positional parameters", $1, $2, etc
    • Jeff Schaller
      Jeff Schaller about 6 years
      4 answers and still no grep!
  • Jeff Schaller
    Jeff Schaller about 6 years
    ./script '/usr/sbin/shutdown -h; x' :)
  • GideokSeong
    GideokSeong about 6 years
    Thank you very much and it was very helpful. By the way, how would you know that regular expression? such as =~ ^[[:alpha:]_][[:alnum:]_]*$ ]]
  • Jeff Schaller
    Jeff Schaller about 6 years
    Please don't rush to accept this answer, particularly since I avoided using grep! =~ accepts regular expressions, so I just did it in-shell. To learn more, start with conditional expressions and man -s7 regex for a list of character classes. See the regular-expression tag on this site for more, such as unix.stackexchange.com/questions/119905/…
  • Angel Todorov
    Angel Todorov about 6 years
    Can use extended pattern instead of regex: [[ $1 == [[:alpha:]_]*([[:alnum:]_]) ]]
  • Stéphane Chazelas
    Stéphane Chazelas about 6 years
    _ is a valid variable name. In most locales, [a-z] matches a lot more than the 26 English letters from a to z. Same for [0-9] and 0123456789 in some shells like bash or ksh93.
  • Kusalananda
    Kusalananda about 6 years
    @StéphaneChazelas Thanks for the reminders!
  • jesse_b
    jesse_b about 6 years
    @StéphaneChazelas: Updated again, however I cannot get it to accept a[1] either way.
  • jesse_b
    jesse_b about 6 years
    @StéphaneChazelas: Quoted $var to prevent globbing. Also I would argue that it's a good thing to tell students RANDOM, EUID, and UID are not valid variable names. :p
  • jesse_b
    jesse_b about 6 years
    Modified again.
  • Stéphane Chazelas
    Stéphane Chazelas about 6 years
    That's better now. So I'll clean-up the comments. Remaining issues: it still outputs some error messages without outputting no for most invalid variables (+, é, ''...). If more code is added to that script, calling it with things like PATH or IFS can have nasty side effects. It would report no for valid variable names that correspond to readonly ones (like UID, BASHOPTS...) or special ones set by bash like RANDOM, OPTIND. It returns yes for that-script 2 test.