diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js
index 16f6f1b7..777f21f3 100755
--- a/src/core/config/OperationConfig.js
+++ b/src/core/config/OperationConfig.js
@@ -3196,7 +3196,69 @@ const OperationConfig = {
outputType: "html",
args: [
]
- }
+ },
+ "Head": {
+ description: [
+ "Like the UNIX head utility.",
+ "
",
+ "Gets the first $Number of lines.",
+ "
",
+ "Optionally you can select all but the last $Number of lines.",
+ "
",
+ "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
+ ].join("\n"),
+ run: StrUtils.runHead,
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Delimiter",
+ type: "option",
+ value: StrUtils.DELIMITER_OPTIONS
+ },
+ {
+ name: "Number",
+ type: "number",
+ value: 10,
+ },
+ {
+ name: "All but last $Number of lines",
+ type: "boolean",
+ value: false,
+ },
+ ]
+ },
+ "Tail": {
+ description: [
+ "Like the UNIX tail utility.",
+ "
",
+ "Gets the last $Number of lines.",
+ "
",
+ "Optionally you can select all lines after line $Number.",
+ "
",
+ "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
+ ].join("\n"),
+ run: StrUtils.runTail,
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Delimiter",
+ type: "option",
+ value: StrUtils.DELIMITER_OPTIONS
+ },
+ {
+ name: "Number",
+ type: "number",
+ value: 10,
+ },
+ {
+ name: "Start from line $Number",
+ type: "boolean",
+ value: false,
+ },
+ ]
+ },
};
export default OperationConfig;
diff --git a/src/core/operations/StrUtils.js b/src/core/operations/StrUtils.js
index 816d4abc..4ba0b18e 100755
--- a/src/core/operations/StrUtils.js
+++ b/src/core/operations/StrUtils.js
@@ -537,6 +537,61 @@ const StrUtils = {
return output;
},
+ /**
+ * Head lines operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ runHead: function(input, args) {
+ let delimiter = args[0],
+ number = args[1],
+ allBut = args[2];
+
+ delimiter = Utils.charRep[delimiter];
+ let splitInput = input.split(delimiter);
+
+ return splitInput
+ .filter((line, lineIndex) => {
+ lineIndex += 1;
+
+ if (allBut) {
+ return lineIndex <= splitInput.length - number;
+ } else {
+ return lineIndex <= number;
+ }
+ })
+ .join(delimiter);
+ },
+
+ /**
+ * Tail lines operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ runTail: function(input, args) {
+ let delimiter = args[0],
+ number = args[1],
+ allBut = args[2];
+
+ delimiter = Utils.charRep[delimiter];
+ let splitInput = input.split(delimiter);
+
+ return splitInput
+ .filter((line, lineIndex) => {
+ lineIndex += 1;
+
+ if (allBut) {
+ return lineIndex >= number;
+ } else {
+ return lineIndex > splitInput.length - number;
+ }
+ })
+ .join(delimiter);
+ },
};
export default StrUtils;
diff --git a/test/tests/operations/StrUtils.js b/test/tests/operations/StrUtils.js
index ada89137..d1af9dd8 100644
--- a/test/tests/operations/StrUtils.js
+++ b/test/tests/operations/StrUtils.js
@@ -34,4 +34,224 @@ TestRegister.addTests([
}
],
},
+ {
+ name: "Head 0",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 0, false]
+ }
+ ],
+ },
+ {
+ name: "Head 1",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 1, false]
+ }
+ ],
+ },
+ {
+ name: "Head 2",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 2, false]
+ }
+ ],
+ },
+ {
+ name: "Head 6",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 6, false]
+ }
+ ],
+ },
+ {
+ name: "Head big",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 100, false]
+ }
+ ],
+ },
+ {
+ name: "Head all but 0",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 0, true]
+ }
+ ],
+ },
+ {
+ name: "Head all but 1",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 1, true]
+ }
+ ],
+ },
+ {
+ name: "Head all but 2",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 2, true]
+ }
+ ],
+ },
+ {
+ name: "Head all but 6",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 6, true]
+ }
+ ],
+ },
+ {
+ name: "Head all but big",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Head",
+ "args": ["Line feed", 100, true]
+ }
+ ],
+ },
+ {
+ name: "Tail 0",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 0, false]
+ }
+ ],
+ },
+ {
+ name: "Tail 1",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 1, false]
+ }
+ ],
+ },
+ {
+ name: "Tail 2",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 2, false]
+ }
+ ],
+ },
+ {
+ name: "Tail 6",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 6, false]
+ }
+ ],
+ },
+ {
+ name: "Tail big",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 100, false]
+ }
+ ],
+ },
+ {
+ name: "Tail all but 0",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 0, true]
+ }
+ ],
+ },
+ {
+ name: "Tail all but 1",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [1, 2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 1, true]
+ }
+ ],
+ },
+ {
+ name: "Tail all but 2",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [2, 3, 4, 5, 6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 2, true]
+ }
+ ],
+ },
+ {
+ name: "Tail all but 6",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [6].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 6, true]
+ }
+ ],
+ },
+ {
+ name: "Tail all but big",
+ input: [1, 2, 3, 4, 5, 6].join("\n"),
+ expectedOutput: [].join("\n"),
+ recipeConfig: [
+ {
+ "op": "Tail",
+ "args": ["Line feed", 100, true]
+ }
+ ],
+ },
]);