Bojangles
Bojangles

Reputation: 101513

Retrieve "TODO" lines from a text file

I'm editing a project in GEdit (text editor). When I type TODO it highlights it yellow for future reference. I have quite a few of these TODOs around the place.

To make it clearer what I need to do, can anyone show me a way to extract any TODO lines from a bunch of files and put them into one text file called, for example, TODOs.txt?

I have something like this:

// TODO: Error handling.

And want it to be put in a file like this:

* <file name> <line number> Error handling

A Linux application (CLI, GUI don't mind) would be preferable, but a regex script or another method someone could come up with would be cool.

Upvotes: 3

Views: 3510

Answers (7)

Edward Renton
Edward Renton

Reputation: 51

Hade the same issue so came up with a simple python script to do it using git grep...

import os
import subprocess
from contextlib import suppress

result = subprocess.run("git grep -l TODO", stdout=subprocess.PIPE)
lst = result.stdout.decode().split("\n")

with suppress(Exception): lst.remove(os.path.basename(__file__)) # remove this filename
with suppress(Exception): lst.remove("") # remove empty filename

todos = []
for file in lst:
    with open(file) as reader:
        for idx, row in enumerate(reader):
            if "TODO" in row: todos.append((file, idx, row))

for todo in todos:
    print(todo)

Upvotes: 0

chutsu
chutsu

Reputation: 14103

If the file is git version controlled, you might want to reuse git's grep. To grep for TODOs in your source files you type the following command at the root of the repo

git grep TODO

The command outputs something like this:

[~/projects/atl][ros] > git grep TODO
atl_gazebo/src/plugins/quadrotor_gplugin.cpp:  // TODO: switch to attitude controller when in offboard mode

To include the line number add the -n flag:

[~/projects/atl][ros] > git grep -n TODO
atl_gazebo/src/plugins/quadrotor_gplugin.cpp:92:  // TODO: switch to attitude controller when in offboard mode

For more options docs are here.

Upvotes: 3

pragmatic
pragmatic

Reputation: 11

Riley Lark's (and EdoDodo's) answers are probably the most concise, however to not have the literal "TODO" text to show up in the output, you could use ack:

ack --no-group 'TODO (.*)' --output=' $1' > TODOs.txt

Output:

lib/Example.pm:102: Move _cmd out into a separate role
lib/Example.pm:364: Add a filename parameter
lib/Example2.pm:45: Move comment block to POD format

If you wanted some slightly different formatting then adding the --no-group option would provide:

lib/Example.pm
102: Move Move _cmd out into a separate role
364: Add a filename parameter

lib/Example2.pm
45: Move comment block to POD format

Upvotes: 1

Edoardo Pirovano
Edoardo Pirovano

Reputation: 8334

Here's a command that will find all the TODOs in the directory you're in, and it's subdirectories, and put them in a text file:

grep 'TODO' -rn * > TODOs.txt

EDIT:

To remove the unnecessary output before it, you could use this command instead:

grep 'TODO.*' -rno * > TODOs.txt

Upvotes: 0

thkala
thkala

Reputation: 86403

This will recursively find any line with '// TODO' in any file under the current directory:

grep -rn '// *TODO' .

This cleans up the output a bit:

grep -rn '// *TODO' . | while read l; do
        echo "$(cut -d : -f 1,2 <<<"$l"):$(sed 's|.*//[[:space:]]*TODO||' <<<"$l")"
done

Note that this might break if there are colons (:) in your source code file names.

You can put the output in a file with a final redirection.

EDIT:

This is even better:

grep -rn '// *TODO' . | sed 's|^\([^:]*:[^:]*:\).*//[[:space:]]*TODO|\1|'

Upvotes: 0

Riley Lark
Riley Lark

Reputation: 20890

try grep TODO -rnf * > TODOs.txt

Upvotes: 2

DVK
DVK

Reputation: 129481

If your list of files which has TODO in them is stored in a file, say named "file_list.txt", run:

grep -n `cat file_list.txt` > TODOs.txt

This will retrieve a list of all the lines containing "TODO" string, prepended with filename and line #, and store that in TODOs.txt

Upvotes: 1

Related Questions