3

How to validate the following file content?

That should be include single integer/float number by bash Regular Expression or any other idea with awk/sed.

example:

cat  /var/VERSION/Version_F35_project_usa
2.8
  • You want to validate that is says "2.8"? – Jesse_b Aug 14 '17 at 15:09
  • no this example num , any float or integer number – jango Aug 14 '17 at 15:09
  • 1
    I'm not sure what you mean by that. You want to validate that the file only contains a number? Validate means to prove that something is true. What do you want to check for? The existence of a number or the existence of 2.8? – Jesse_b Aug 14 '17 at 15:11
  • 6
    Do you want any float (like 1.2e-2, -1, 0x9.d7p-3) or just the 1.2, -1.2 variations? Or something that looks more like a version number like 1.2.3, 1.2pre2, 1.2-3, 12.2a... Should the locale's decimal separator (. or ,) be honoured? – Stéphane Chazelas Aug 14 '17 at 15:43
5

Use grep, if matched means that's valid:

grep -P '^[0-9]+(\.[0-9]+)?$' infile.txt

The above regex can be used in sed or awk or any command.

sed -n -Ee '/^[0-9]+(\.[0-9]+)?$/p'
awk '/^[0-9]+(\.[0-9]+)?$/'

Here is also checking if file match with this regex or not.

awk '/^[0-9]+(\.[0-9]+)?$/{print "matched";exit} {print "not-matched";exit}' file
  • The [1-9]+ fails to match 104.23, as 0.0, also 0. and plain 0. – Arrow Aug 15 '17 at 0:16
  • Hi @Arrow, This will match as your desired one '^[0-9]+\.?([0-9]+)?$' , by the way I don't think so x. is considering valid by OP's question even in edit history I did this but I fixed to don't match x. – αғsнιη Aug 15 '17 at 2:52
  • Technically, those check if any line in the file (only the first for the last one) match the pattern, not the file as a whole. – Stéphane Chazelas Aug 15 '17 at 10:14
  • Note that there's nothing perl specific in the first grep one, so you could do grep -xE '[0-9]+(\.[0-9]+)?' to make it standard/portable. See also sed '/^[0-9]\{1,\}\(\.[0-9]\{1,\}\)\{0,1\}$/!d' for a standard/portable equivalent of your sed one. – Stéphane Chazelas Aug 15 '17 at 10:16
6

If you want to check that the file as a whole contains a number of decimal digits, optionally followed by a . and more digits and then an optional newline character, you could do:

is_valid() {
   awk 'END{exit(!(NR == 1 && /^[0-9]+(\.[0-9]+)?$/))}' < "$1"
}

if is_valid /var/VERSION/Version_F35_project_usa; then
  echo the file has the right kind of content
else
  echo >&2 the file does not have the right kind of content
fi
  • This is interesting. Can you explain a bit about $1 part and >&2 part?The way I understand it is, it looks for x.x type number and stores it as variable $1. Then if $1 exists then print true statement, else print no right content. – mamun Aug 15 '17 at 0:14
  • This doesn't allow +2 or -25, rejects ` 1.3` and accepts as valid 0000.00. Not to mention 1,345,234.75434, 1.345.234,75434 or 1e3. – Arrow Aug 15 '17 at 0:23
  • @Arrow. Indeed. But it specifies exactly what it matches and the OP didn't answer when I asked what floats they wanted be matched (see comments on the question). If you want to nitpick, you might argue that with some awk implementations it could give false positives on things like 1<NUL>whatever. – Stéphane Chazelas Aug 15 '17 at 10:07
  • The question do state single integer/float number. AFAICT +25 is an integer, as is 1e3 and ` 1.3` seems to me to match a float. So: no, your regex does not match what was asked, only a limited solution to some parcial view of the problem. – Arrow Aug 16 '17 at 0:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.