diff --git a/README.md b/README.md
index 8937fbefc6..23ee60d9c6 100644
--- a/README.md
+++ b/README.md
@@ -1397,7 +1397,8 @@ The process ID is: 420
#### String Manipulation
-
+- `append(suffix, s)`master Append `suffix` to whitespace-separated
+ strings in `s`.
- `quote(s)` - Replace all single quotes with `'\''` and prepend and append
single quotes to `s`. This is sufficient to escape special characters for
many shells, including most Bourne shell descendants.
diff --git a/src/function.rs b/src/function.rs
index b7e03e5553..2ed098367a 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -20,6 +20,7 @@ pub(crate) enum Function {
pub(crate) fn get(name: &str) -> Option {
let function = match name {
"absolute_path" => Unary(absolute_path),
+ "append" => Binary(append),
"arch" => Nullary(arch),
"blake3" => Unary(blake3),
"blake3_file" => Unary(blake3_file),
@@ -105,6 +106,15 @@ fn absolute_path(context: &FunctionContext, path: &str) -> Result Result {
+ Ok(
+ s.split_whitespace()
+ .map(|s| format!("{s}{suffix}"))
+ .collect::>()
+ .join(" "),
+ )
+}
+
fn arch(_context: &FunctionContext) -> Result {
Ok(target::arch().to_owned())
}
diff --git a/tests/functions.rs b/tests/functions.rs
index 2c0e814340..3cc1d40e5d 100644
--- a/tests/functions.rs
+++ b/tests/functions.rs
@@ -481,6 +481,26 @@ fn trim_end() {
assert_eval_eq("trim_end(' f ')", " f");
}
+#[test]
+fn append() {
+ assert_eval_eq("append('8', 'r s t')", "r8 s8 t8");
+ assert_eval_eq("append('.c', 'main sar x11')", "main.c sar.c x11.c");
+ assert_eval_eq("append('-', 'c v h y')", "c- v- h- y-");
+ assert_eval_eq(
+ "append('0000', '11 10 01 00')",
+ "110000 100000 010000 000000",
+ );
+ assert_eval_eq(
+ "append('tion', '
+ Determina
+ Acquisi
+ Motiva
+ Conjuc
+ ')",
+ "Determination Acquisition Motivation Conjuction",
+ );
+}
+
#[test]
#[cfg(not(windows))]
fn join() {