Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odd Sed Error Message

Tags:

sed

bash-3.2$ sed -i.bakkk -e "s#/sa/#/he/#g" .*
sed: .: in-place editing only works for regular files

I try to replace every /sa/ with /he/ in every dot-file in a folder. How can I get it working?

like image 929
Léo Léopold Hertz 준영 Avatar asked Jul 24 '09 21:07

Léo Léopold Hertz 준영


3 Answers

Use find -type f to find only files matching the name .* and exclude the directories . and ... -maxdepth 1 prevents find from recursing into subdirectories. You can then use -exec to execute the sed command, using a {} placeholder to tell find where the file names should go.

find . -type f -maxdepth 1 -name '.*' -exec sed -i.bakkk -e "s#/sa/#/he/#g" {} +

Using -exec is preferable over using backticks or xargs as it'll work even on weird file names containing spaces or even newlines—yes, "foo bar\nfile" is a valid file name. An honorable mention goes to find -print0 | xargs -0

find . -type f -maxdepth 1 -name '.*' -print0 | xargs -0 sed -i.bakkk -e "s#/sa/#/he/#g"

which is equally safe. It's a little more verbose, though, and less flexible since it only works for commands where the file names go at the end (which is, admittedly, 99% of them).

like image 112
John Kugelman Avatar answered Sep 28 '22 02:09

John Kugelman


Try this one:

sed -i.bakkk -e "s#/sa/#/he/#g"  `find .* -type f -maxdepth 0 -print`

This should ignore all directories (e.g., .elm, .pine, .mozilla) and not just . and .. which I think the other solutions don't catch.

like image 39
Chris J Avatar answered Sep 28 '22 01:09

Chris J


The glob pattern .* includes the special directories . and .., which you probably didn't mean to include in your pattern. I can't think of an elegant way to exclude them, so here's an inelegant way:

sed -i.bakkk -e "s$/sa/#/he/#g" $(ls -d .* | grep -v '^\.\|\.\.$')
like image 30
Adam Rosenfield Avatar answered Sep 28 '22 02:09

Adam Rosenfield