GAP has operations DisplayString, ViewSrting and PrintString documented here. Usually, displaying an object produces a human-readable relatively complete and verbose output, viewing produces a short and concise output, and printing produces an output in a complete form which is GAP readable (if at all possible), such that reading the output into GAP produces an object which is equal to the original one.
Depending on the type of the object, they may delegate to each other in the order specified here.
In the example in question, we have
gap> PrintString(x);
"PartialPerm( \>[ 1, 2 ], \<\>[ 3, 4 ]\<\> )\<"
gap> ViewString(x);
"\>[\>1\<,\>3\<\<]\>[\>2\<,\>4\<\<]"
gap> DisplayString(x);
"<object>\n"
As you see, the output have additional control characters \< (ASCII 1) and \> (ASCII 2) that allow proper line breaks. The function StripLineBreakCharacters (see here) may be used to remove them:
gap> StripLineBreakCharacters(PrintString(x));
"PartialPerm( [ 1, 2 ], [ 3, 4 ] )"
gap> StripLineBreakCharacters(ViewString(x));
"[1,3][2,4]"
gap> StripLineBreakCharacters(DisplayString(x));
"<object>\n"
There is also String (see here) which should approximate as closely as possible the character sequence you see if you print an object:
gap> String(x);
"PartialPerm( [ 1, 2 ], [ 3, 4 ] )"
Perhaps for partial permutations that's the best option.
String- will update the answer now. – Olexandr Konovalov Jan 03 '19 at 19:22