---json { "page_id": "hq020bdc3ffohcie057hm" } --- ====== How to create a CSV dynamically with a script? ====== ===== About ===== This ''howto'' will show you how you can create any resource dynamically with a [[:docs:resource:script|script]]. In this example, we will create a [[docs:resource:csv|CSV]] but you can create any type of resource on the fly. ===== Steps ===== ==== Pre-requisites ==== You should have followed the [[script|bash script howto]] to understand how to execute and pass ''arguments'' via a [[:docs:resource:command|command]] ==== The bash script that creates the csv ==== The bash script that will be executed is: * a ''hello-csv'' sample [[:docs:resource:script|script]] * that * accepts the number of lines generated as first argument (default to 1) * is located in the ''command'' directory of the [[:docs:connection:howto|howto connection]] * outputs a [[:docs:resource:csv|CSV]] We can print the content with the [[:docs:tabul:data:concat|data cat]] command tabul data cat command/hello-csv@howto #!/usr/bin/env bash # The first argument is the number of lines generated, default to 1 LINES=${1:-1} # Print CSV headers echo "Id;Greeting" # Generate the lines for ((i=1; i<=LINES; i++)); do if [ "$i" -gt 1 ]; then echo "$i;Hello World $i times" continue fi echo "$i;Hello World $i time" done ==== Simple execution ==== We can execute it to test that it works. tabul data print --strict-selection '(command/hello-csv@howto)@tmp' # The quotes are only mandatory in bash because parenthesis are a bash token (ie subshell) # We execute it with a strict-selection flag so that we get an error if the executable file is not found. (command/hello-csv@howto)@tmp lines -------------------- Id;Greeting 1;Hello World 1 time ==== Generating 3 lines ==== To pass the argument, we have created the following [[:docs:resource:command#manifest|command manifest]] tabul data cat command/hello-csv--command.yml@howto kind: command spec: # the runtime data uri data-uri: (command/hello-csv@howto)@tmp # The data definition (attributes) data-def: # A list of arguments passed to the command arguments: - 3 # The first argument, the number of lines # Create a file with the CSV extension stdout-data-uri: 'execute/${execution_start_time}-${executable_logical_name}.csv@tmp' Executing it yield 3 lines tabul data print --strict-selection command/hello-csv--command.yml@howto # We execute it with a strict-selection flag so that we get an error if the file is not found. (command/hello-csv@howto)@tmp Id;Greeting --------------------- 1;Hello World 1 time 2;Hello World 2 times 3;Hello World 3 times ==== Defining the CSV structure ==== Unfortunately, we can see that the CSV does not split correctly the columns because the separator is a semicolon '';'' and not a the default colon '','' character. To define the csv structure, we created the following [[:docs:resource:csv#manifest|csv manifest]] tabul data cat command/hello-csv--csv.yml@howto kind: csv spec: # the command manifest data-uri: hello-csv--command.yml@md data-def: # the character separator delimiter-character: ; # the columns to define the data type columns: - name: Id type: integer - name: Greeting type: varchar Executing it yield now a [[:docs:resource:csv|CSV]] with 2 columns tabul data print --strict-selection command/hello-csv--csv.yml@howto # We execute it with a strict-selection flag so that we get an error if the file is not found. execute/20251110-204747-850-hello-csv.csv@tmp Id Greeting -- ------------------- 1 Hello World 1 time 2 Hello World 2 times 3 Hello World 3 times ===== Conclusion ===== This example shows how you can create dynamic resources. It's the way to hack Tabulify and because it's based on programing language, the sky is your only limit.