@@ -314,6 +314,42 @@ fn apply_range<T: Clone>(items: &[T], range: &RangeSpec) -> Vec<T> {
314314 }
315315}
316316
317+ /// Unescape \n, \t, \r, in argument strings
318+ fn unescape ( s : & str ) -> String {
319+ let mut out = String :: new ( ) ;
320+ let mut chars = s. chars ( ) . peekable ( ) ;
321+ while let Some ( c) = chars. next ( ) {
322+ if c == '\\' {
323+ match chars. peek ( ) {
324+ Some ( 'n' ) => {
325+ out. push ( '\n' ) ;
326+ chars. next ( ) ;
327+ }
328+ Some ( 't' ) => {
329+ out. push ( '\t' ) ;
330+ chars. next ( ) ;
331+ }
332+ Some ( 'r' ) => {
333+ out. push ( '\r' ) ;
334+ chars. next ( ) ;
335+ }
336+ Some ( & next) => {
337+ // Leave as-is: keep the backslash and the next char
338+ out. push ( '\\' ) ;
339+ out. push ( next) ;
340+ chars. next ( ) ;
341+ }
342+ None => {
343+ out. push ( '\\' ) ;
344+ }
345+ }
346+ } else {
347+ out. push ( c) ;
348+ }
349+ }
350+ out
351+ }
352+
317353fn apply_ops ( input : & str , ops : & [ StringOp ] ) -> Result < String , String > {
318354 let mut val = Value :: Str ( input. to_string ( ) ) ;
319355 let mut last_split_sep: Option < String > = None ;
@@ -351,7 +387,7 @@ fn apply_ops(input: &str, ops: &[StringOp]) -> Result<String, String> {
351387 } ,
352388 StringOp :: Join { sep } => match & val {
353389 Value :: List ( list) => {
354- val = Value :: Str ( list. join ( sep) ) ;
390+ val = Value :: Str ( list. join ( & unescape ( sep) ) ) ;
355391 }
356392 Value :: Str ( s) => {
357393 val = Value :: Str ( s. clone ( ) ) ;
@@ -463,7 +499,7 @@ fn main() {
463499 let input = match cli. input {
464500 Some ( input) => input,
465501 None => match read_stdin ( ) {
466- Ok ( input) => input,
502+ Ok ( input) => input. trim_end ( ) . to_string ( ) ,
467503 Err ( e) => {
468504 eprintln ! ( "Error: {}" , e) ;
469505 std:: process:: exit ( 1 ) ;
@@ -484,6 +520,12 @@ fn main() {
484520mod tests {
485521 use super :: * ;
486522
523+ #[ test]
524+ fn test_join_newline ( ) {
525+ let input = "a,b,c" ;
526+ assert_eq ! ( process( input, r"{split:,:..:join:\\n}" ) . unwrap( ) , "a\n b\n c" ) ;
527+ }
528+
487529 #[ test]
488530 fn test_split_index ( ) {
489531 let input = "a,b,c" ;
@@ -921,4 +963,3 @@ mod tests {
921963 ) ;
922964 }
923965}
924-
0 commit comments