Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Lorz

macrumors newbie
Original poster
Nov 4, 2021
24
1
Hello!
I don't have much experience in using Mac terminal and want find and replace some expressions in several files. I found a command
find /<path>/<files> -type f -exec sed -i 's/<old>/<new>/g' {} \;
working for linux terminal to change words in several files placed in the same directory.
But this command doesn't work for with Mac terminal and - believe me or not - after 2 hours of googling I haven't found a command for Mac terminal yet.

Is here anybody who knows the right command? ..I'll praise you!
(Sorry, if my writing isn't fully correct, I'm writing in German English...)
 
You need to pass an extension to -i which will make a copy of the old file. For example:
Code:
sed -i .backup 's/foo/bar/g' file.txt
So file.txt will have the replaced text and file.txt.backup will be the old copy of the file before the replace.
 
Replacements can be done inplace with

Code:
sed -i '' 's/old/new/' file

Simplest example
cat.jpg
 
Thanx to @mlsusa and @bogdanw for answering quick and helpfully.
I would like to have the path of the concerned files inside the command to limit the effect. Yesterday I tried several commands without setting the path absolut and then Mac asked me for getting permission to change images-, video- and other stuff-files. What I definitely not wanted. Although my terminal script was placed at the right directory not including an image- or videofiles.
 
You need to pass an extension to -i which will make a copy of the old file. For example:
Code:
sed -i .backup 's/foo/bar/g' file.txt
So file.txt will have the replaced text and file.txt.backup will be the old copy of the file before the replace.
When I use

"sed -i .backup 's//RoentgenPeaks/PPPPPPPPPP/g' file.txt" or "sed -i .backup 's//RoentgenPeaks/PPPPPPPPPP/g' file.tex"

I get

"sed: 1: "s//RoentgenPeaks/PPPPPP ...": bad flag in substitute command: 'P'"
 
I get the answer

"sed: file: No such file or directory"

...I think there is a miss-understanding. I want to change the file content not the name of the file.
Sorry, I presumed you would understand from the example.
file is the path to your desired file
Without knowing what exactly are you trying to achieve, it’s hard to suggest solutions.
I use a QuickAction to replace a pattern of text inside files. Something like this:
QuickAction.jpg

Use Quick Action workflows on Mac https://support.apple.com/guide/automator/use-quick-action-workflows-aut73234890a/mac
 
@bogdanw thanx for idea with Quick Action. That looks smart. But I would like to learn to do it with Mac Terminal to be able to do much more stuff that might be not possible with Quick Action.
 
It's one line in Terminal:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.txt
replaces the word “old” with the word “new” in all files with the extension .txt in the folder ~/Desktop/aaa/
 
It's one line in Terminal:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.txt
replaces the word “old” with the word “new” in all files with the extension .txt in the folder ~/Desktop/aaa/
Does this work with tex-Files? Or should type .tex?
 
When I use

"sed -i .backup 's//RoentgenPeaks/PPPPPPPPPP/g' file.txt" or "sed -i .backup 's//RoentgenPeaks/PPPPPPPPPP/g' file.tex"

I get

"sed: 1: "s//RoentgenPeaks/PPPPPP ...": bad flag in substitute command: 'P'"
There's an extra slash in your sed command:
Code:
s//RoentgenPeaks/PPPPPPPPPP/g
Note the two slashes after the "s".

It should be:
Code:
s/RoentgenPeaks/PPPPPPPPPP/g
 
I tried
Code:
sed -i '' 's/Strahlungsverteilung/SSSSSSSSSS/' /Users/myname/Desktop/KSQMKopieZuMExp/*.txt
got
Code:
got zsh: no matches found: /Users/lorenzgroth/Desktop/KSQMKopieZuMExp/*.txt

and I tried
Code:
sed -i '' 's/Strahlungsverteilung/SSSSSSSSSS/' /Users/myname/Desktop/KSQMKopieZuMExp/*.tex
got
Code:
got sed: RE error: illegal byte sequence
 
I created an txt-file with the expression "Strahlungsverteilung" in it. And tried

Code:
sed -i '' 's/Strahlungsverteilung/SSSSSSSSSS/' /Users/lorenzgroth/Desktop/KSQMKopieZuMExp/*.txt

and got nothing. And no changes in file content.



Mac "preferes" rtf. So I created an rtf-file with the expression "Strahlungsverteilung" in it. And tried

Code:
sed -i '' 's/Strahlungsverteilung/SSSSSSSSSS/' /Users/lorenzgroth/Desktop/KSQMKopieZuMExp/*.rtf

and got nothing. And no changes in file content.



Edit: I had to close TEXTEdit. And I had an UTF8 vs Latin Problem.
Now: I get changes. Big Thanx!
But is it possible to use this command also for tex-Files?
 
Last edited:
Everything is OK now.
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.tex
works fine - when there is no latin code.

Done - thanx to everyone, especially @bogdanw !!!
 
Edit: I had to close TEXTEdit. And I had an UTF8 vs Latin Problem.
Now: I get changes. Big Thanx!
But is it possible to use this command also for tex-Files?
sed will work actually work on any file, your LaTeX/TeX files too. As you already discovered: beware of the encoding of your files. ?
 
Everything is OK now.
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.tex
works fine - when there is no latin code.
Done - thanx to everyone, especially @bogdanw !!!
Glad it works. Just a clarification, sed works differently on macOS than on Linux.
Without a flag, the substitution is made for the first instance of a word/expression on a line. For most uses, that’s enough.
But if you have a line like this: Strahlungsverteilung some text Strahlungsverteilung, only the first one will be replaced.
If you want to be sure that all instances of a word/expression are replaced, use the g flag.

Code:
sed -i '' 's/old/new/g' ~/Desktop/aaa/*.tex

More about sed flags from man sed:
The value of flags in the substitute function is zero or more of the following:
N Make the substitution only for the N'th occurrence of the regular expression in the pattern space.
g Make the substitution for all non-overlapping matches of the regular expression, not just the first one.
p Write the pattern space to standard output if a replacement was made. If the replacement string is identical to that which it replaces, it is still considered to have been a replacement.
w file Append the pattern space to file if a replacement was made. If the replacement string is identical to that which it replaces, it is still considered to have been a replacement.
i or I Match the regular expression in a case-insensitive way.
 
There's an extra slash in your sed command:
Code:
s//RoentgenPeaks/PPPPPPPPPP/g
Note the two slashes after the "s".

It should be:
Code:
s/RoentgenPeaks/PPPPPPPPPP/g

Or, if the pattern is "/RoentgenPeaks", need to escape the slash:

s/\/RoentgenPeaks/PPPPPPP/g
 
What if I need to change Python paths in a bunch of .py files? The issue is the slashforwards. I am not a dev so please bear with me.

I need to change "/usr/bin/python" to "/usr/local/bin/python" in all *.py files in a subfolder.

Thanks.
 
What if I need to change Python paths in a bunch of .py files? The issue is the slashforwards.
As NoBoMac explained above, copy-paste in Terminal

Code:
sed -i '' 's/\/usr\/bin\/python/\/usr\/local\/bin\/python/g'

add a space, drag-drop the subfolder and write /*.py after it.
The final command should look something like this:
sed -i '' 's/\/usr\/bin\/python/\/usr\/local\/bin\/python/g' /Users/stooovie/Desktop/subfold/*.py
 
Last edited:
Comin back to this topic.
Now I need to do recursive a replacement. Is it possible to change something in
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.tex
to include subdirectories and keep enclose only tex-files?
 
Comin back to this topic.
Now I need to do recursive a replacement. Is it possible to change something in
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*.tex
to include subdirectories and keep enclose only tex-files?
I am not exactly sure what you want to achieve - you want to change content only in .tex-files in a directory tree?

for i in `find *.tex` ; do sed -i '' 's/old/new/g' $i; done

find i => will iterate over all the files in the folder and in subfolders.

sed -i => will replace in the files the relevant string if exists.
 
to include subdirectories and keep enclose only tex-files?
Something as simple as
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*/*.tex
can work for immediate subfolders of aaa
or if you want to define the depth of search
Code:
find ~/Desktop/aaa/ -maxdepth 5 -name '*.tex' -exec sed -i '' 's/old/new/' {} +

You want to delete files that are not tex?
 
I am not exactly sure what you want to achieve - you want to change content only in .tex-files in a directory tree?

for i in `find *.tex` ; do sed -i '' 's/old/new/g' $i; done

find i => will iterate over all the files in the folder and in subfolders.

sed -i => will replace in the files the relevant string if exists.
Yes, I want do make the changes in the folder and its subfolders. (..sorry for using "strange vocabulary", I am german
).
Your code works on my computer only in the folder. In the subfolder I can not find changes.
 
Something as simple as
Code:
sed -i '' 's/old/new/' ~/Desktop/aaa/*/*.tex
can work for immediate subfolders of aaa
or if you want to define the depth of search
Code:
find ~/Desktop/aaa/ -maxdepth 5 -name '*.tex' -exec sed -i '' 's/old/new/' {} +

You want to delete files that are not tex?
Thank you for this solution @bogdanw , works fine! I am so glad, now!
No, I don't want to delete files.
Background: I'm using latex for long time now. And I got lots of "old" tex-files, encoded in ISO-8859-1. I did the converting to utf8 and now I need to replace the term "Latin1" with "utf8". So in my case it's
Code:
sed -i '' 's/latin1/utf8/' /Users/myname/Testordner/*/*.tex
I got 7,959 tex-files on my harddrive so it is really important to let the renaming process do a program.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.