Tired right now, I'll write an explanation tomorrow.
[Try it online][1].
Explanation
The main idea here is to find the longest line (we'll call this length T), then pad all lines to the same length and concatenate them (this new string is U). This way only a single counter is needed to move in the map. Adding/subtracting 1 means moving to the right/left in the same line, adding/subtracting T means moving down/up one line.
qN/ e# Split the input on newlines _:, e# Push a list of the line lengths $W=:T e# Grab the maximum length and assign to T f{Se]} e# Right-pad each line with spaces to length T s:U e# Concatenate lines and assign to U Now it's time to set up the loop.
,T- e# Push len(U) - T e# i.e. position of first char of the last line {...}g e# Do-while loop e# Pops condition at the end of each iteration The loop body uses a lookup table and eval to choose what to do. At the beginning of each iteration, the top stack element is the current position. Underneath it there are all the processed NSWE directions. At the end of the iteration, the new direction is placed underneath the position and a copy of it is used as the condition for the loop. Non-zero characters are truthy. When an X is encountered, 0 is pushed as the direction, terminating the loop.
_U= e# Push the character in the current position "><^vx"# e# Find the index in "><^Vx" "..."4/ e# Push the string and split every 4 chars e# This pushes the following list: e# [0] (index '>'): "1+'E" pos + 1, push 'E' e# [1] (index '<'): "1-'W" pos - 1, push 'W' e# [2] (index '^'): "T-'N" pos - T, push 'N' e# [3] (index 'v'): "T+'S" pos + T, push 'S' e# [4] (index 'X'): "0" push 0 =~ e# Get element at index and eval _@\ e# From stack: [old_directions position new_direction] e# To stack: [old_directions new_direction position new_direction] e# (You could also use \1$) e# new_direction becomes the while condition and is popped off Now the stack looks like this: [directions 0 position]. Let's generate the output.
;; e# Pop position and 0 off the stack ] e# Wrap directions in a list e` e# Run length encode directions e# Each element is [num_repetitions character] { e# For each element: (+ e# Swap num_repetitions and character }% e# End of map (wraps in list) ", "* e# Join by comma and space