In programming and scripting, commenting code is an essential practice that can improve code readability, facilitate collaboration, and make code maintenance easier. The Command Line Interface (CLI) provides a convenient way to toggle line comments in a file.
In this tutorial, we’ll explore the process of toggling comments using the command line in Bash.
2. Sample Task and Scope
Our objective is to comment or uncomment specified lines within a file using command-line tools. We won’t address inline comments, but rather lines that begin with a hash symbol (#), possibly preceded by whitespace characters. Removing inline comments in Bash can require specialized tools.
In the simplest case, such as when dealing with configuration files, lines can begin with a # symbol to indicate they’re just comments without any other effect.
Let’s consider a file named app.conf and display its contents with cat:
$ cat app.conf # Set the log level to one of: DEBUG, INFO, WARNING, ERROR # And enable database logging # log_level = INFO # db_logging = true
Here, each line begins with a # symbol, and we wish to uncomment the third and fourth lines of this file.
In more complex cases, the # symbol may be preceded and followed by any number of whitespace characters.
For instance, let’s look at the operation.py file containing Python code:
$ cat operation.py # this is a comment def operation(x, y): # z = x + y z = x * y return z a, b = 2, 3 print(operation(a,b))
Python is sensitive to indentation. In this case, we want to uncomment the third line and comment out the fourth, changing the underlying operation from a product to a summation. Both lines are indented, and the indentation should be preserved if the operation function is to run successfully.
Let’s now address the issue of commenting and uncommenting specific lines in these files.
3. Toggling Line Comments Without Indentation
The app.conf file contains lines that begin with a # symbol without any indentation. We can use the sed command to remove or add a # symbol at the beginning of any line:
$ sed -i '3,4 s/^#//' app.conf $ cat app.conf # Set the log level to one of: DEBUG, INFO, WARNING, ERROR # And enable database logging log_level = INFO db_logging = true
Here, we used sed to replace any # symbol at the beginning of a line with the empty string. The caret (^) symbol signifies the beginning of a line. In this case, we apply the replacement only over the specified lines in the file, that is, lines 3 through 4. Also, we save the changes in-place within the file as indicated by the -i option.
This way, we uncommented the last two lines in the file, thereby specifying the log level and activating database logging.
To re-comment lines 3 and 4 in app.conf, we can use sed again:
$ sed -i '3,4 s/^/#/' app.conf $ cat app.conf # Set the log level to one of: DEBUG, INFO, WARNING, ERROR # And enable database logging # log_level = INFO # db_logging = true
This time, sed adds a # symbol at the beginning of a line, while applying this only to lines 3 and 4. The result is that we’ve restored the configuration file to its original form.
4. Toggling Indented Line Comments
While commenting and uncommenting lines that begin with a # symbol is straightforward with sed, we need to modify the regex used when dealing with indented line comments.
To uncomment the third line correctly in the operation.py file, we need to preserve the indentation and remove any whitespace following the original # symbol:
$ sed -i -E '3 s/^(\s*)#\s*/\1/' operation.py $ cat operation.py # this is a comment def operation(x, y): z = x + y z = x * y return z a, b = 2, 3 print(operation(a,b))
Here, we used the -E option with sed to enable extended regex. The ^(\s*)#\s* regex indicates a pattern at the start of a line consisting of zero or more whitespace characters followed by a # symbol and zero or more whitespace characters.
The characters preceding the # symbol are captured in a group indicated within parentheses. We then replace the entire pattern with the first captured group, signified by \1. Thus, the indentation within the group is preserved in the final version of the line. We apply this substitution only for the third line, and we save the result in-place within the file.
To comment out the fourth line, we use sed with a modified regex expression:
$ sed -i -E '4 s/^(\s*)(.*)/\1#\2/' operation.py $ cat operation.py # this is a comment def operation(x, y): z = x + y #z = x * y return z a, b = 2, 3 print(operation(a,b))
In this case, we capture two groups. The first capture group consists of zero or more whitespace characters at the beginning of a line, while any remaining characters fall into the second group. As a replacement for this pattern, we insert a # symbol between the two captured groups. This effectively preserves the initial indentation when commenting out a line.
5. Using a Script
To facilitate the process of commenting and uncommenting lines in a file, we can wrap the sed commands within script files:
$ cat uncomment #!/usr/bin/env bash sed -i -E "$1 s/^(\s*)#\s*/\1/" "$2"
We pass two arguments to the uncomment script:
- line number(s) where sed should be applied
- file to perform modifications in
Likewise, the comment script takes the same number and types of arguments:
# cat comment #!/usr/bin/env bash sed -i -E "$1 s/^(\s*)(.*)/\1#\2/" "$2"
$ chmod +x comment uncomment $ ./comment 3 operation.py $ cat operation.py # this is a comment def operation(x, y): #z = x + y #z = x * y return z a, b = 2, 3 print(operation(a,b))
Here, we’ve commented out the third line.
Now, let’s uncomment the fourth line:
$ ./uncomment 4 operation.py $ cat operation.py # this is a comment def operation(x, y): #z = x + y z = x * y return z a, b = 2, 3 print(operation(a,b))
Finally, we run the Python script:
$ python3 operation.py 6
Notably, the product operation is successful and we’ve correctly preserved the indentation within the function.
In this article, we’ve explored how to toggle line comments in a file using sed while taking indentation into account. Toggling comments in a file from the CLI provides a convenient way to manage and maintain code.