I would like to put the full directory path of the filename inside the file.

So, if there is foo/bar/main.cpp, then the path is added at the top of the file main.cpp.

Can anyone help me with a bash command?

I tried all the find , exec and xargs methods, but doing echo or cat provide me the content of the file and not the filename itself. Maybe the answers would make it clear how filenames are extracted from find exec or any other method.

Expected output in a file /foo/bar/main.cpp

int main ( .... ) {
  • "at the top of the file"? You want to write into the file? – pfnuesel Jun 22 '17 at 22:17
  • Can you show expected output? – pfnuesel Jun 22 '17 at 22:19
  • You want to add all path's to all files to main.cpp? Or in each file the path to the file in question? – pfnuesel Jun 22 '17 at 22:22
  • @pfnuesel: why downvote? in each file the path to the file in question. – infoclogged Jun 22 '17 at 23:12
  • I didn't downvote. – pfnuesel Jun 23 '17 at 0:08

If you use gnu find/sed, this should work:

cd /
find subpath_with_files -name .hg -prune -o -type f -exec sed -i -e '1i\{}' {} +

If you want to add it as a comment, you could use something like this:

cd /
find subpath_with_files -name .hg -prune -o -type f -exec sed -i '1i\# Filename: {}' {} +

The trick is that {} can be used more than once in the exec parameter of find.

I'm pruning .hg assuming that this is in a mercurial repository. This can be .git or other. The files you are modifying should be in a repository of some kind so that you can know that the change worked as desired, and you can roll back with a revert command if not.

  • If I understand the question correctly, he wants absolute path's. To make that work with your command, one would need to cd / and then find dir .... – pfnuesel Jun 22 '17 at 22:21
  • Good point. Edited. – Chad Skeeters Jun 23 '17 at 0:36
  • @ChadSkeeters can you please explain the + in the end coz I guess \; will equally work? Also what is the signififance of '1' in the sed. Looks like the line number 1 for me? – infoclogged Jun 23 '17 at 8:20
  • 1
    @infoclogged Yes 1 is the line number. – pfnuesel Jun 23 '17 at 11:42
  • 1
    Find spawns sed as a new process. When you run it with \;, it spawns one process for each file. When you run it with +, it will pass some large number of files as multiple arguments to one instance of the sed process making it run much faster. – Chad Skeeters Jun 23 '17 at 22:38

You can use a script like this:

#!/usr/bin/env bash

for i; do
    if [ "${i:0:1}" = "/" ]; then
        # Absolute path
        sed -i "1i${i}" "${i}"
        # Relative path
        sed -i "1i${PWD}/${i}" "${i}"

It takes any number of files as positional parameters, in which the absolute path will be written, i.e. you can call it like this:

./addPath foo/bar.cpp foo/bar/main.cpp /home/user/main.cpp

It accepts absolute and relative paths', and you can mix them, as you can see in the example.

Be careful, there is no undo functionality! :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.