Issue
I need to check that a file follows a struture like this before using it
1:15:0:.0504:.1092:0:0:0:0:0:0:0:0:
2:15:1:0:0:.0504:.0504:0:0:0:0:0:0:3:.345:3.4:
hello
3:5:0:0:0:0:0:hello:0:0:0:0:0:
5:13:1:0:-3:0:0:.0378:0:0:0:0:0:
6:10:0:0:0:0:0:.0540:0:0:.0840:0:343:345:32:33:.1:
Where each real number is separated by ":"
pattern="^(-?[0-9]+(\.[0-9]*)?(:[0-9]*(\.[0-9]*)*)*):$"
while IFS= read -r linea; do
if [[ -n $linea ]]; then
if [[ $linea =~ $pattern ]]; then
echo "Valid line: $linea"
else
echo "Invalid line: $linea"
fi
fi
done < "$file"
Outputs:
Valid line: 1:15:0:.0504:.1092:0:0:0:0:0:0:0:0:
Valid line: 2:15:1:0:0:.0504:.0504:0:0:0:0:0:0:3:.345:3.4:
Invalid line: hello
Invalid line: 3:5:0:0:0:0:0:hello:0:0:0:0:0:
Invalid line: 5:-13:1:0:0:0:0:.0378:0:0:0:0:0:
Valid line: 6:10:0:0:0:0:0:.0540:0:0:.0840:0:343:345:32:33:.1:
And all lines should be valid except 3 and 4
Solution
Please read why-is-using-a-shell-loop-to-process-text-considered-bad-practice.
Since your subject line says you want to match
the pattern: "real_number:real_number: ... :real_number:"
and given your current regexp, this might be adequate for your needs, using any awk:
$ awk '{print (/^((-?[0-9]+(\.[0-9]+)?|\.[0-9]+):)+$/ ? "Valid" : "Invalid"), "line:", $0}' file
Valid line: 1:15:0:.0504:.1092:0:0:0:0:0:0:0:0:
Valid line: 2:15:1:0:0:.0504:.0504:0:0:0:0:0:0:3:.345:3.4:
Invalid line: hello
Invalid line: 3:5:0:0:0:0:0:hello:0:0:0:0:0:
Valid line: 5:13:1:0:-3:0:0:.0378:0:0:0:0:0:
Valid line: 6:10:0:0:0:0:0:.0540:0:0:.0840:0:343:345:32:33:.1:
or either of these:
awk '{print (/^((-?[0-9]+)?(\.[0-9]+)?:)+$/ ? "Valid" : "Invalid"), "line:", $0}' file
awk '{print (/^((-?[0-9]+)?(\.[0-9]+)?:)+$/ && !/(^|:):/ ? "Valid" : "Invalid"), "line:", $0}' file
Answered By - Ed Morton Answer Checked By - Senaida (WPSolving Volunteer)