1. Introduction

File creation is one of the fundamental aspects of Linux systems and plays a pivotal role in the overall functionality and organization of the operating environment. In Linux, file creation is about establishing a structured and systematic approach to storing and retrieving information.

The ability to create multiple files with specific properties, such as prefixes and extensions, can be helpful in various scenarios:

  • enhancing organizational clarity
  • batch processing
  • automated workflows
  • scripting and testing

In this tutorial, we’ll learn how to create multiple files with specific prefixes and extensions using the Linux CLI.

The code in this tutorial underwent testing on a Debian 12 (Bookworm) system using GNU Bash 5.1.16.

2. Using POSIX Commands

We can use POSIX commands like printf, touch, and brace expansion to create multiple files having specific prefixes and extensions.

2.1. Using touch With Brace Expansion

In general, we can create files using the touch command.

Let’s combine the touch command with brace expansion to create multiple files:

$ touch step_{1..10}.txt

This command creates ten files with names step_1.txt to step_10.txt in the current working directory. Each file has the prefix step_ and the extension .txt.

Additionally, we can use the brace expansion to create specific files by going over each element in the provided sequence:

$ touch part_{header,body,footer}.csv

Here, we create three different files: part_header.csv, part_body.csv, and part_footer.csv, in the current working directory. In this command, we used part_ as the prefix and .csv as the extension for the files we create.

2.2. Using printf and Extended Arguments

We can use the printf command to create a list of strings that serves as an argument list for the subsequent command. With the help of extended arguments (xargs), we can pass each element from the argument list to the touch command:

$ printf step_'%s'.txt' ' {A..F} | xargs touch

The above command can be divided into two parts: the part preceding the pipe (|) and the part following the pipe.

The first part preceding the pipe (|) generates an argument list with file names having step_ as the prefix and .txt as the extension. The second part following the pipe processes each element from the previously generated argument list to create files with the provided names.

Let’s break down this command to understand each option it employs:

  • printf is the command that formats and prints the text
  • step_’%s’.txt’ ‘ is the string format for printf where ‘%s’ is a placeholder for each value in the sequence resulting from the brace expansion
  • {A..F} is the brace expansion that generates a sequence of characters from A to F
  • | (pipe) takes the output of the preceding command and passes it as input to the following command
  • xargs takes each space-separated item from the input and passes it to the touch command
  • touch is then used to create empty files with the specified names

Overall, this command creates six files with names step_A.txt to step_F.txt. All the files share a common prefix step_ and a common extension .txt.

3. Using Shell Loops

Bash provides concise ways to express loops, making it efficient for quick tasks. We can create multiple files with specific prefixes and extensions using shell loops: for and while.

3.1. Bash for Loop

The for loop is a control flow statement commonly used to repeatedly execute code based on a specified sequence or range of values. We can specify the number of iterations using the control expression:

$ for ((i=5; i<=10; i++)); do >> "file_$i.csv"; done

This command results in six files with names file_5.csv to file_10.csv. In this case, we used file_ as the prefix and .csv as the extension for the files created.

Let’s understand each option used in this command:

  • for initiates the for loop construct in bash
  • ((i=5; i<=10; i++)) is the control expression that initializes i to 5, continues the loop as long as the value of i is less than or equal to 10, and increments i by 1 in each iteration
  • do marks the beginning of the code block to be executed in each iteration
  • >> is the append redirection operator that appends the output to a file without overwriting its existing content, in this case, an empty line
  • “file_$i.csv” is the filename where $i is the placeholder for a numerical variable from the control expression
  • done marks the end of the for loop

Moreover, we can also use brace expansion to define the control expression in the for loop:

$ for i in {5..10}; do >> "file_$i.csv"; done

Both of the above commands are the same and accomplish identical goals resulting in six files with the same naming convention.

3.2. Using while Loop

The while loop is another control flow statement used to execute a block of code repeatedly as long as a specified condition evaluates to true.

Let’s create multiple files with newdata_ as the prefix and .txt as the extension using the while loop:

$ i=1; while [ "$i" -le 9 ]; do >> "newdata_$i.txt"; i=$(($i + 1)); done

The above command creates nine files with names newdata_1.txt to newdata_9.txt.

Let’s take a closer look at the new option used in this command:

  • i=1 initializes the variable to 1
  • while invokes the while loop and continues as long as the condition evaluates to true
  • [ “$i” -le 9 ] is the condition for a while loop construct, checking if the value of i is less than or equal to 9
  • i=$(($i + 1)) increments the value of i by 1 in each iteration of the loop

At the end of this while loop, the value of $i should be 10, i.e., greater than 9. So, let’s check the value of $i:

$ echo $i
10

We can use the redirection operator (>) instead of the append redirection operator (>>) in the above commands to overwrite the existing files, if any.

Additionally, we can use the string comparison operators in Bash to compare two strings for evaluating conditions. There are two string comparison operators in Bash: string equal (=) and string not equal (!=).

4. Using Interpreted Programming Languages

The task of creating multiple files with specific prefixes and extensions can be accomplished using various scripting and programming interpreters. For simplicity, we’ll limit ourselves to only a few programming languages in this tutorial.

4.1. Perl

In Perl, we can construct a similar for loop to the one demonstrated in Bash earlier:

$ perl -e 'for ($i=1;$i<=10;$i++) { open($f, ">", "file_$i.pl"); }'

This perl command creates 10 files with the prefix file_ and the extension .pl.

The perl -e construct invokes perl for one-liners directly from the command line. The open() system call creates the files with specified names, in this case, file_$i.pl where $i acts as a placeholder for a numerical variable that takes values from the loop iteration.

4.2. Python

Python also has the for loop command to execute a code block repeatedly:

$ python -c 'for i in range(2,8): open("file_"+str(i)+".py", "w");'

This command creates six files with the names file_2.py to file_7.py. In this example, we used file_ as the prefix and .py as the extension to create multiple files.

The python -c invokes the Python interpreter in one-liner mode, for i in range(2,8) is a loop iterating over the range from 2 to 7, and open() opens a file with the provided name in the write-only mode.

The range() function in Python can work with the upper limit alone. For example, range(8) iterates the loop from 0 to 7.

4.3. Ruby

Ruby has a different syntax for iteration:

$ ruby -e '(1..10).each { |i| File.open("file_"+i.to_s+".rb", "w") }'

This one-liner creates 10 files in the current directory having the prefix file_ and the extension .rb.

The (1..10).each from the above command creates a range from 1 to 10 and iterates over each element in the range. i.to_s in the file naming convention converts the loop variable i to a string.

5. Conclusion

In this article, we explored several ways to create multiple files with specific prefixes and extensions. Of course, we can select any method depending on our preferences.

First, we discussed the usage of POSIX-standard tooling and shell loops to create multiple files with specific prefixes and extensions. Then, we practiced two different versions of the control expression in the Bash for loop.

Finally, we used the one-liners from higher-level programming languages to achieve the same goal of creating multiple files with specific prefixes and extensions.