0

我对 bash 脚本不是很熟悉,但是假设我有一个文件textfile.txt,其中包含名称和邮件,该文件由几行组成,这些模式出现了多次:

name@surname.net;othername.othersurname;name@surname.net;othername.othersurname;name@surname.net;...

我想从这个列表中禁止所有不是邮件的条目。所以假设我的可执行文件是 file.sh 并且我运行 sh file.sh textfile.txt

#!/bin/bash

if [–f $1];

awk -F ";" '{//here comes what I am looking for
}' $1

else 

echo "there is no such file"

fi

我不知道我可以使用哪种语法来获取最后过滤的条目(以检查是否没有@将其从列表中删除的标志)。我试图用谷歌搜索但没有成功

4

3 回答 3

1

我不知道awk对不起,但你可以用 perl 做到这一点

perl -p -e 's/;[^;@]+;/;/g'

但这有一个错误,如果该行中的第一个或最后一个条目是无效的电子邮件,它将错过它。要正确解决这些问题,您需要 split/check/join 开始变得凌乱的单行

perl -p -e 'join(";",grep(/@/,split(";",$_)))'

编辑:糟糕,抱歉,从 ideone 切换到命令行时出错。我错过了返回的作业$_,这是由-p

perl -p -e '$_ = join(";",grep(/@/,split(";",$_)))'
  • split(";",$_)使用分隔符将当前行 ( $_) 拆分为一个元素数组。;
  • grep(/@/,...)然后只返回数组中包含@. 这是我对有效电子邮件地址的简单测试。如果你想更彻底,你可以对电子邮件地址使用更严格的正则表达式。也许/^[^\s@]+@[^\s@]+\.[^\s@]+$/
  • 然后将join(";"...)有效的电子邮件地址重新组合成一个;分隔字符串。
于 2013-05-30T16:26:02.110 回答
1

这是在没有 awk 或 perl 的 bash 脚本中执行此操作的一种方法...

origfile=$1
copyfile=`mktemp`

for email in `sed 's/;/\n/g' $origfile | grep "@"`; do
    printf "$email;" >> $copyfile
done

#you may want to check that $copyfile is valid in some way before the next step
mv $copyfile $origfile
于 2013-05-30T21:24:38.583 回答
0

这里有一个awk解决方案。但只是awk,所以我不建议将它包含在 shell 脚本中。它应该可以从命令行运行它:

awk '

    ## Split (in input) and join (in output) fields with colon.
    BEGIN { FS = OFS = ";" }
    {   
        ## Traverse all fields and delete those that do not contain one "@".
        for ( i = 1; i <= NF; i++ ) { if ( index( $i, "@" ) == 0 ) { $i = "" } } 

        ## There will be some consecutive colons between those fields deleted.
        ## Keep only one.
        gsub( /;{2,}/, ";" )

        ## Print the whole line only with emails.
        print
    }   

' infile

使用您的示例行,它给出:

name@surname.net;name@surname.net;name@surname.net
于 2013-05-30T21:22:05.040 回答