I found the following awesome little script at link

$ find /home/bruno/old-friends -type f -exec sed -i 's/ugly/beautiful/g' {} \;

But I really do not understand the final bit

{} \;

Could someone please explain??



This is not exactly a sed syntax problem, it's a find syntax problem.

The {} is a container that will replace the name of the file being processed by the sed command.

If you use find like this:

$ find . -type f -name *.py -exec head {} \;

This will find Python scripts and show you the head of each file. If you have three scripts in the current directory:

  • 1.py
  • 2.py
  • 3.py

The {} will contain each file name and execute the head command on each file.

The -exec argument needs a ; at the end so it can recognize the end of the command arguments (sed in this case) but, in order to protect ; from expansion you need to escape it with the \.

Remember that you can execute several commands at a time if you use the ;:

$ ls; pwd;

This will list directories (ls) and print your working directory (pwd). The -exec argument also needs the ;. But since you don't want to confuse the ; that separates commands with the ; that is part of the -exec argument of find, you need to escape it with the \.

Alternatively, you can use quotes around the ;:

$ find /home/bruno/old-friends -type f -exec sed -i 's/ugly/beautiful/g' {} ";"

I hope I made myself clear

| improve this answer | |

I have been using an about.com Linux page for a while that covers

find - search for files in a directory hierarchy

as a reference for a while and it covers the part of the command you are asking about.

find . -type f -exec file '{}' \;

Runs `file' on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though ';' could have been used in that case also.

So I think your command should have semicolons around your braces just to be safe.

Reference Links:

Article explaining the find command

| improve this answer | |

With exec (and not xargs), the {} has to be included as it gets replaced by name of the file that is targeted by the find command; it is a placeholder that is normally quoted so that if any target files have spaces in them, the command will still run successfully on all the files. The semicolon has to be included as it ends the command, just like when separating multiple commands on the command line. It has to be escaped in this case so that the find command receives it from the shell unexpanded (as a literal). There are many tutorials about this online, see, for example, this useful article.

Another excellent, and indeed essential, article is that on the Wooledge site that explains extremely well the find command, exec, and the importance of quoting various elements in your command or script. I have found that article and the site as a whole very useful for learning bash and bash scripting.

| improve this answer | |

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.