Linux

從原始電子郵件中解析文件名

  • October 31, 2017

需要在電子郵件中獲取逗號分隔的文件名列表。以下是一些輸入範例,其中 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 的單個命令將不勝感激。

在電子郵件中獲取逗號分隔的文件名列表

GNU awk解決方案:

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

佐藤桂是對的。這是一個快速的 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

引用自:https://unix.stackexchange.com/questions/401667