我想用脚本验证文本文件。
要验证的文件是:
FDFHDK JKL
1545665 152
HDKFHDK UHG
YRYRUBH DFG
867HDKE WER
有效行必须与正则表达式匹配'[A-Z]{7}+[[:space:]]+[A-Z]{3}'
。
如果所有行均有效,脚本将显示一条消息,表明文件正常。
如果至少有一行与正则表达式不匹配,则脚本应显示一条消息并显示与正则表达式不匹配的行。
脚本是:
#!/usr/bin/env bash
result=""
output=$(grep -vE '[A-Z]{7}+[[:space:]]+[A-Z]{3}' "$1" |wc -l)
if [[ $output > 0 ]]
then
echo "These lines don't match:"
result="${resultado} $(grep -vE '[A-Z]{7}+[[:space:]]+[A-Z]{3}' "$1") \n"
echo -e $result
else
echo "The text file is valid"
fi
预期输出是
These lines don't match
FDFHDK JKL
1545665 152
867HDKE WER
但我越来越
These lines don't match:
FDFHDK JKL 1545665 152 867HDKE WER
所以实际的脚本没有考虑换行符。
答案1
绝对没有理由使用中间变量来存储命令的输出只是为了执行测试或输出该数据。
#!/bin/sh -
if grep -q -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1"
then
echo 'Does not verify. Bad lines follow...'
grep -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1"
fi
正则表达式已被更正,以删除+
后的多余内容{7}
。该if
语句直接测试退出状态grep
。语句grep
中的命令if
以及后面的命令用于强制-x
进行整行匹配,第一个grep
语句用于-q
在第一个匹配处停止而不输出任何内容。
代码中的实际问题是使用$result
不带引号的,这会导致 shell 将值拆分为空格、制表符和换行符,然后对生成的单词执行文件名通配。然后将最终的单词集作为参数给出,echo
并用空格作为分隔符来打印它们。
如果您担心运行grep
两次,则仅运行一次并将其输出存储到临时文件中:
#!/bin/sh -
tmpfile=$(mktemp)
if grep -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1" >"$tmpfile"
then
echo 'Does not verify. Bad lines follow...'
cat -- "$tmpfile"
fi
rm -f -- "$tmpfile"
答案2
我建议这个替代方案:
match="$(grep -vEx '[A-Z]{7}[[:space:]]+[A-Z]{3}' "$1")"
[[ "${#match}" -ne 0 ]] && printf "%b\n" "Bad lines:\n${match[@]}"
Bad lines:
FDFHDK JKL
1545665 152
867HDKE WER
笔记来自@他们的回答:
正则表达式已更正,删除后面多余的
+
内容{7}