我对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
我不知道我可以使用哪种语法获取最后一个已过滤的条目(以检查是否没有@
符号将其从列表中删除)。我试图谷歌但没有成功
答案 0 :(得分:1)
我不知道awk
抱歉,但您可以使用perl
perl -p -e 's/;[^;@]+;/;/g'
但是这里有一个错误,如果该行中的第一个或最后一个条目是无效的电子邮件,它将会错过它。要正确解决这些问题,您需要拆分/检查/加入,它开始变得混乱为单行
perl -p -e 'join(";",grep(/@/,split(";",$_)))'
编辑:糟糕,抱歉,从ideone切换到命令行时出错。我错过了回到$_
的作业,这是-p
perl -p -e '$_ = join(";",grep(/@/,split(";",$_)))'
split(";",$_)
使用$_
作为分隔符,将当前行(;
)拆分为元素数组。grep(/@/,...)
然后只返回包含@
的数组元素。这是我对有效电子邮件地址的简单测试。如果你想要更多,你可以使用更严格的正则表达式的电子邮件地址。也许/^[^\s@]+@[^\s@]+\.[^\s@]+$/
join(";"...)
将有效的电子邮件地址重新组合为;
分隔的字符串。答案 1 :(得分: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
答案 2 :(得分: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