Shell脚本找到分隔符

时间:2015-09-01 16:28:52

标签: bash shell awk

我有一个包含三列的文件,其中有一个管道作为分隔符。由于某些错误,文件中的某些行可以有“,”而不是“|”。我想输出所有这些错误的行。

2 个答案:

答案 0 :(得分:2)

你也可以使用grep,它更复杂:

egrep "\|.*\|.*\|" input
echo No pipe
egrep "^[^\|]*$" input
echo One pipe
egrep "^[^\|]*\|[^\|\]*$" input
echo 3+ pipe
egrep "\|[^\|]*\|[^\|\]*\|" input

在组合greps之前,首先介绍新变量 p(管道)和n(无管道)

p="\|"
n="[^\|]*"
echo "p=$p, n=$n"
echo No pipe
egrep "^$n$" input
echo One pipe
egrep "^$n$p$n$" input
echo 3+ pipe
egrep "$p$n$p$n$p" input

现在把所有人聚集在一起

egrep "^$n$|^$n$p$n$|$p$n$p$n$p" input

编辑:注释和变量名称是关于“斜杠”,但它们是管道(带有反斜杠)。这有点令人困惑。

答案 1 :(得分:1)

要使用awk计算列数,您可以使用NF变量:

$ cat file
ABC|12345|EAR
PQRST|123|TWOEYES
ssdf|fdas,sdfsf
$ awk -F\| 'NF!=3' file
ssdf|fdas,sdfsf

但是,根据问题和评论的各种修订,这似乎并未涵盖数据损坏的所有可能方式。

更好的方法是定义数据必须遵循的精确格式。例如,假设一条线是"正确的"如果它是三列,只有第一个和第三个字母,第二个数字,你可以编写以下脚本来匹配所有不符合的行:

awk -F\| '!(NF==3 && $1$3 ~ /^[a-zA-Z]+$/ && $2+0==$2)' file

测试(注意只有第二行(符合要求)不打印):

$ cat file
A,BC|12345|EAR
PQRST|123|TWOEYES
ssdf|fdas,sdfsf
ABC|3983|MAKE,
sf dl lfsdklf |kldsamfklmadkfmask |mfkmadskfmdslafmka
ABC|abs|EWE
sdf|123|123
$ awk -F\| '!(NF==3&&$1$3~/^[a-zA-Z]+$/&&$2+0==$2)' file
A,BC|12345|EAR
ssdf|fdas,sdfsf
ABC|3983|MAKE,
sf dl lfsdklf |kldsamfklmadkfmask |mfkmadskfmdslafmka
ABC|abs|EWE
sdf|123|12

您可以根据您认为有效的输入调整上述命令以满足您的特定需求。例如,如果您还想将每行的长度限制为50个字符,则可以执行

awk -F\| '!(NF==3 && $1$3 ~ /^[a-zA-Z]+$/ && $2+0==$2 && length($0)<50)' file
相关问题