需要在电子邮件中获取逗号分隔的列表文件名。以下是一些输入示例,其中 1 有很多特殊字符:
Content-Disposition: attachment;
filename="How-To_21_Monitor_Mode_Deployment_Guide.pdf"; size=3886046;
creation-date="Fri, 27 Oct 2017 16:23:20 GMT";
modification-date="Fri, 27 Oct 2017 16:24:30 GMT"
Content-Disposition: attachment; filename="How-To_24_Low_Impact_Mode.pdf";
size=6714113; creation-date="Fri, 27 Oct 2017 16:23:20 GMT";
modification-date="Fri, 27 Oct 2017 16:24:31 GMT"
Content-Disposition: attachment;
filename="SBTGxYVWPE1wI9SAjl5b2PUfF1LCjbU3aChsoch5eXuI4GrIP9bRhfiaOuwL1U
;.,~!@#$%....txt"; size=3966; creation-date="Fri, 27 Oct 2017 16:23:20 GMT";
modification-date="Fri, 27 Oct 2017 16:23:20 GMT"
这是可行的,但如果超过 3 行就不够高效了:
grep --no-group-separator --line-buffered -A 2 '^Content-Disposition: ' | sed -e '/\;$/!{N;s/\n//}' -n -e 's/.*filename\=//p' | sed -e 's/ size\=.*//' | sed 's/\;$//' | sed ':a;N;$!ba;s/\n/,/g'
试图让它与单个 sed 行一起工作:
sed -n '/^Content-Disposition: /,/\"\; size\=/{/\;$/!{x;N;s/\n//g}};s/.*filename\=//p;s/ size\=.*//;s/\;$//;:a;N;$!ba;s/\n/,/g;
如果最好使用 sed 单个命令,我们将不胜感激。
答案1
Satō Katsura 是对的。这是一个快速的 Perl 脚本,假设您在文件中拥有完整的电子邮件消息。
cpan install Email::MIME File::Slurp::Tiny
perl -MEmail::MIME -MFile::Slurp::Tiny=read_file -wE '
my $email = Email::MIME->new( read_file(shift @ARGV) );
my $count = 0;
$email->walk_parts(sub {
my $part = shift;
my %header = $part->header_str_pairs;
if (exists $header{"Content-Disposition"}) {
my ($filename) = $header{"Content-Disposition"} =~ m/(?<=filename=")([^"]+)/;
say ++$count .":". $filename;
}
})
' email.eml
答案2
获取电子邮件中以逗号分隔的文件名列表
GNUawk解决方案:
awk -v RS='\n\n' 'BEGIN{ fn="" }
match($0, /filename="([^"]+)";[[:space:]]+size=/, a){
gsub(/[[:space:]]*/, "", a[1]);
fn = (fn!=""? fn", ":"")a[1]
}END{ print fn }' file
fn
- 包含所有文件名的结果字符串(处理后)-v RS='\n\n'
- 将记录分隔符设置为双换行符/filename="([^"]+)";[[:space:]]+size=/
- 正则表达式模式将每个标头中的文件名捕获Content-Disposition
到匹配数组中a
输出:
How-To_21_Monitor_Mode_Deployment_Guide.pdf, How-To_24_Low_Impact_Mode.pdf, SBTGxYVWPE1wI9SAjl5b2PUfF1LCjbU3aChsoch5eXuI4GrIP9bRhfiaOuwL1U;.,~!@#$%....txt
答案3
RomanPerekhrest 达到 99%,谢谢!这是我使用的最后一行,只需进行一些细微的调整即可处理文件名中的空格并包含字符串周围的引号。在这种情况下 awk 绝对比 sed 更好。
awk -v RS='\n\n' 'BEGIN{ fn="" } match($0, /filename=("[^"]+");[[:space:]]+size=/, a) {gsub(/\n/, "", a[1]);fn = (fn!=""? fn",":"")a[1]}END{ print fn }'