diff --git a/src/parser/shell_expand/mod.rs b/src/parser/shell_expand/mod.rs
index f16a4dfb52d8bfbbe4880db536ca623b95abaec0..070677d325922e5bdbc7f88bbba42cdbee7ae649 100644
--- a/src/parser/shell_expand/mod.rs
+++ b/src/parser/shell_expand/mod.rs
@@ -10,6 +10,7 @@ use self::braces::BraceToken;
 use self::ranges::parse_range;
 pub(crate) use self::words::{Index, Range, Select, WordIterator, WordToken};
 use glob::glob;
+use std::ptr;
 use std::str;
 use types::*;
 use unicode_segmentation::UnicodeSegmentation;
@@ -41,7 +42,7 @@ fn expand_process<E: Expander>(
     expander: &E,
     quoted: bool,
 ) {
-    if let Some(output) = expander.command(command) {
+    if let Some(mut output) = expander.command(command) {
         if quoted {
             let output: &str = if let Some(pos) = output.rfind(|x| x != '\n') {
                 &output[..pos + 1]
@@ -50,15 +51,34 @@ fn expand_process<E: Expander>(
             };
             slice(current, output, selection)
         } else {
-            // TODO: Complete this so that we don't need any heap allocations.
-            //       All that we need is to shift bytes to the left when extra spaces are found.
-            //
-            // unsafe {
-            //     let bytes: &mut [u8] = output.as_bytes_mut();
-            //     bytes.iter_mut().filter(|b| **b == b'\n').for_each(|b| *b = b' ');
-            //     slice(current, str::from_utf8_unchecked(&bytes).trim(), selection)
-            // }
-            slice(current, &output.split_whitespace().collect::<Vec<&str>>().join(" "), selection)
+            // If we ever do something with UTF-8, this won't work
+            unsafe {
+                let mut bytes = output.as_bytes_mut();
+                let bytes_v = bytes.as_mut_ptr();
+                let mut size = bytes.len();
+                let mut i = 0;
+                let mut prev_is_whitespace = true;
+                while i < size {
+                    let is_whitespace = char::is_whitespace(bytes[i] as char);
+                    if is_whitespace {
+                        bytes[i] = b' ';
+                    }
+                    if is_whitespace && prev_is_whitespace {
+                        size -= 1;
+                        if i != size-1 {
+                            let offset = i as isize;
+                            ptr::copy(bytes_v.offset(offset+1), bytes_v.offset(offset), size - i);
+                        }
+                    } else {
+                        i += 1;
+                        prev_is_whitespace = is_whitespace;
+                    }
+                }
+                if prev_is_whitespace {
+                    size -= 1;
+                }
+                slice(current, str::from_utf8_unchecked(&bytes[..size]), selection)
+            }
         }
     }
 }
@@ -559,6 +579,22 @@ mod test {
         }
     }
 
+    struct CommandExpander;
+
+    impl Expander for CommandExpander {
+        fn command(&self, cmd: &str) -> Option<Value> {
+            Some(cmd.to_owned())
+        }
+    }
+
+    #[test]
+    fn expand_process_unquoted() {
+        let mut output = String::new();
+        let line = " Mary   had\ta little  \n\t lamb\t";
+        expand_process(&mut output, line, Select::All, &CommandExpander, false);
+        assert_eq!(output, "Mary had a little lamb");
+    }
+
     #[test]
     fn expand_variable_normal_variable() {
         let input = "$FOO:NOT:$BAR";