I’m trying to pull a spam IP address out of an email header.
Using grep piped to cut works in a shell: grep -F "X-YahooFilteredBulk: " /Users/stevedrenker/Desktop/spamhdrU.txt | cut -f2 -d’ ’
In the “cut” command, the “-f2” says cut out field 2 at delimiter = space (-d’ '). Since there is only one space on this line, I can set the delimiter = space and grab the second field. There will be only one line with "X-YahooFilteredBulk: ", so I’m using the -F option to match fixed strings only.
Trying to get it to work in AppleScript, I first set up a portion of a sample header:
set myHdr to “X-Apparently-To: steve@pacbell.net via 66.163.170.53; Fri, 03 Feb 2006 02:30:12 -0800” & (ASCII character 10) & “X-YahooFilteredBulk: 81.172.67.112” & (ASCII character 10) & “X-Originating-IP: [81.172.67.112]” & (ASCII character 10) & “Authentication-Results: mta103.sbc.mail.re2.yahoo.com” & (ASCII character 10) & “from=yahoo.com; domainkeys=neutral (no sig)”
Then do the shell script using an escaped-quotation mark (") around my search string and quoted form of the header:
do shell script “grep -F "X-YahooFilteredBulk: "” & quoted form of myHdr & " | cut -f2 -d’ '"
It returns only an empty string. Any ideas? TIA, Steve
set myHdr to "X-Apparently-To: steve@pacbell.net via 66.163.170.53; Fri, 03 Feb 2006 02:30:12 -0800" & (ASCII character 10) & "X-YahooFilteredBulk: 81.172.67.112" & (ASCII character 10) & "X-Originating-IP: [81.172.67.112]" & (ASCII character 10) & "Authentication-Results: mta103.sbc.mail.re2.yahoo.com" & (ASCII character 10) & "from=yahoo.com; domainkeys=neutral (no sig)" -- as Unicode text
set ipAddr to (do shell script ("echo \"" & myHdr & "\" | grep -F \"X-YahooFilteredBulk: \" | cut -f2 -d' '"))
--> "81.172.67.112"
You could also use vanilla AppleScript, which is a good bit faster:
set myHdr to "X-Apparently-To: steve@pacbell.net via 66.163.170.53; Fri, 03 Feb 2006 02:30:12 -0800" & (ASCII character 10) & "X-YahooFilteredBulk: 81.172.67.112" & (ASCII character 10) & "X-Originating-IP: [81.172.67.112]" & (ASCII character 10) & "Authentication-Results: mta103.sbc.mail.re2.yahoo.com" & (ASCII character 10) & "from=yahoo.com; domainkeys=neutral (no sig)" -- as Unicode text
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "X-YahooFilteredBulk: "
set ipAddr to paragraph 1 of text item 2 of myHdr
set AppleScript's text item delimiters to astid
ipAddr
--> "81.172.67.112"
Nigel…running the shell approach in Entourage, I get this error when testing with a real message: “Entourage got an error: cut: stdin: line too long”
I didn’t think there were any line length limits. Any idea what could cause this?
tell application “Microsoft Entourage”
set selectedMessages to current messages
set hdrSource to (the headers of theMessage)
if selectedMessages is {} then
display dialog "Please select message(s) before running this script" with icon 1
return
end if
repeat with theMessage in selectedMessages
set ipAddr to (do shell script ("echo \"" & hdrSource & "\" | grep -F \"X-YahooFilteredBulk: \" | cut -f2 -d' '"))
display dialog ipAddr with icon 1
end repeat
Thanks for pointing out the speed advantage of the AppleScript approach. I’m not sure that the “Yahoo Bulk” header will always be in the same position. Doesn’t your approach require positional consistency? How would you modify it to grab that line wherever it exists in the header?
Hi, Steve. I’m afraid don’t know what the “line too long” thing’s about and I don’t have Entourage to try it. However, the third line in your script seems to be out of position. I think it should go inside the repeat.
tell application "Microsoft Entourage"
set selectedMessages to current messages
if selectedMessages is {} then
display dialog "Please select message(s) before running this script" with icon 1
return
end if
repeat with theMessage in selectedMessages
set hdrSource to (the headers of theMessage)
set ipAddr to (do shell script ("echo \"" & hdrSource & "\" | grep -F \"X-YahooFilteredBulk: \" | cut -f2 -d' '"))
display dialog ipAddr with icon 1
end repeat
end tell
If that doesn’t cure the problem, you could try putting 'tell me to ’ in front of the ‘set ipAddr’ line, or putting the line in a separate handler. (But I don’t know if it would help.)
tell application "PowerMail" --"Microsoft Entourage"
set selectedMessages to current messages
if selectedMessages is {} then
display dialog "Please select message(s) before running this script" with icon 1
return
end if
repeat with theMessage in selectedMessages
set hdrSource to (the headers of theMessage)
set ipAddr to my getIPaddr(hdrSource)
display dialog ipAddr with icon 1
end repeat
end tell
on getIPaddr(hdrSource)
return (do shell script ("echo \"" & hdrSource & "\" | grep -F \"X-YahooFilteredBulk: \" | cut -f2 -d' '"))
end getIPaddr
It works wherever the header is ” provided, of course, that it is actually there somewhere. If AppleScript’s text item delimiters are set to "X-YahooFilteredBulk: ", and there’s only one instance of that header in the headers, ‘text item 2’ of the header text will be whatever comes after "X-YahooFilteredBulk: " ” that is, the rest of that line (the IP address) and the remainder of the text. The IP address is thus the first paragraph of the second text item.
However, the method will error if there’s no such header, so you need to check for that:
if (myHdr contains "X-YahooFilteredBulk: ") then
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to "X-YahooFilteredBulk: "
set ipAddr to paragraph 1 of text item 2 of myHdr
set AppleScript's text item delimiters to astid
else
-- Plan B.
end if