I want to change all occurrences of <ga/ to <. With xargs, this works fine:
ls | xargs sed -i 's/<ga\//</g'
GNU Parallel says that it's a direct replacement for xargs, but doing
ls | parallel sed -i 's/<ga\//</g'
results in
/bin/bash: ga//: No such file or directory
for each file in the directory. I'm sure that I'm just forgetting a {} or \; somewhere, but the answer still alludes me.
ls | parallel -q sed -i 's/<ga\//</g'
Related
I have a directory containing many different folders. In these are some php files. I need to change line nr 1 in all files that match a certain string, in all those folders.
All the files I need to change look something this on line nr 1: <?php some text><?php
I need to replace all those 1st lines with "<?php"
I tried this:
grep -rl something /somedir/folder/ | xargs sed -i '' '1s/.*/<?php/
But it only replaces one of the files in the first folder.
I also tried:
grep -rnw something /somedir/folder/ | xargs sed -i '' '1s/.*/<?php/
But then I get this error:
sed: /somedir/folder//1.php:1:<?php: No such file or directory
Any idea how I can fix this?
sed -i -e 's/<\?php.*<\?php/<?php/' `find ./ -type f`
To explain:
sed -i
Run, with sed editing in-place
-e 's/
a replacement command, replacing
<\?php.*<\?php
two consecutive php opening statements (escaping the question marks, because this is a regex)
/
with
<?php
one php opening statement
/'
once per line.
`find ./ -type f`
for everything in this folder that's a file.
find ./ -iname "*.php" -exec sed '1 s/^<?php some text><?php$/<?php/' -i {} \;
I don't know what the intention of the empty string was, when executing sed. Without it it works totally fine for me:
grep -rl something /somedir/folder/ | xargs sed -i '1s/.*/<\?php/'
grep -rl something /somedir/folder/ | xargs sed -i '' '1s/.*/<\?php/'
This sort of works. But it only changes the file it finds first. And not all files. So basically with this I would have to run it 100 times if I have 100 files =)
Any idea how I can get around that?
I found the solution. Now, since I am on OSX, apparently sed does not work exactly the same way as on Linux. Which I did not know. But this is how it can be done:
find ./ -name \*.php -exec sed -i '' -e '1s/.*/<?php/' {} \;
I don't understand exactly why it needs to be like this, but it works.
I run this command to find and replace all occurrences of 'apple' with 'orange' in all files in root of my site:
find ./ -exec sed -i 's/apple/orange/g' {} \;
But it doesn't go through sub directories.
What is wrong with this command?
Here are some lines of output of find ./:
./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
Your find should look like that to avoid sending directory names to sed:
find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
For larger s&r tasks it's better and faster to use grep and xargs, so, for example;
grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Since there are also macOS folks reading this one (as I did), the following code worked for me (on 10.14)
egrep -rl '<pattern>' <dir> | xargs -I# sed -i '' 's/<arg1>/<arg2>/g' #
All other answers using -i and -e do not work on macOS.
Source
This worked for me:
find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orange|"
Found a great program for this called ruplacer
https://github.com/dmerejkowsky/ruplacer
Usage
ruplacer before_text after_text # prints out list of things it will replace
ruplacer before_text after_text --go # executes the replacements
It also respects .gitignore so it won't mess up your .git or node_modules directories (find . by default will go into your .git directory and can corrupt it!!!)
I think we can do this with one line simple command
for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ās/eth0/eth1/ā $i; done
Refer to this page.
In linuxOS:
sed -i 's/textSerch/textReplace/g' namefile
if "sed" not work try :
perl -i -pe 's/textSerch/textReplace/g' namefile
I just want to batch modify the suffix of the files,but it doesn't work!
The command line I used as below:
ls *html | xargs -I{} echo "\`echo {} | sed 's/html/css/g'\`"
However, when I just used ls *html,it shows:
file1.html file2.html file3.html file4.html file5.html
used ls *html | sed 's/html/css/g',it shows as I expected!
like this:
file1.css file2.css file3.css file4.css file5.css
I work on Mac OS. Could anyone give me some suggestions?
Thans in advance.
Because the backquotes are in double quotes, it gets executed immediately by the shell and not by xargs on each file.
The result is the same as
ls *html | xargs -I{} echo "{}"
However, if you use single quotes, you run into other troubles. You end up having to do something like this:
ls *html | xargs -I{} sh -c 'echo `echo {} | sed '\''s/html/css/g'\''`'
but it gets to be a mess, and we haven't even got to the actual renaming yet.
Using a loop is a bit nicer:
for file in *html; do
newname=${file%html}css
mv "$file" "$newname"
done
Using GNU Parallel:
ls *html | parallel echo before {} after {.}.css
Trying to use the beauty of Sed so I don't have to manually update a few hundred files. I'll note my employer only allows use of Win8 (joy), so I use Cygwin all day until I can use my Linux boxes at home.
The following works on a Linux (bash) command line, but not Cygwin
> grep -lrZ "/somefile.js" . | xargs -0 -l sed -i -e 's|/somefile.js|/newLib.js|g'
sed: can't read ./testTarget.jsp: No such file or directory
# works
> sed -i 's|/somefile.js|/newLib.js|g' ./testTarget.jsp
So the command by itself works, but not passed through Xargs. And, before you say to use Perl instead of Sed, the Perl equivalent throws the very same error
> grep -lrZ "/somefile.js" . | xargs -0 perl -i -pe 's|/somefile.js|/newLib.js|g'
Can't open ./testTarget.jsp
: No such file or directory.
Use the xargs -n option to split up the arguments and force separate calls to sed.
On windows using GnuWin tools (not Cygwin) I found that I need to split up the input to sed. By default xargs will pass ALL of the files from grep to one call to sed.
Let's say you have 4 files that match your grep call, the sed command will run through xargs like this:
sed -i -e 's|/somefile.js|/newLib.js|g' ./file1 ./file2 ./subdir/file3 ./subdir/file4
If the number of files is too large sed will give you this error.
Use the -n option to have xargs call sed repeatedly until it exhausts all of the arguments.
grep -lrZ "/somefile.js" . | xargs -0 -l -n 2 sed -i -e 's|/somefile.js|/newLib.js|g'
In my small example using -n 2 will internally do this:
sed -i -e 's|/somefile.js|/newLib.js|g' ./file1 ./file2
sed -i -e 's|/somefile.js|/newLib.js|g' ./subdir/file3 ./subdir/file4
I had a large set of files and directories (around 3000 files), and using xargs -n 5 worked great.
When I tried -n 10 I got errors. Using xargs --verbose I could see some of the commandline calls were getting cut off at around 500 characters. So you may need to make -n smaller depending on the path length of the files you are woking with.
I have a renamed js file which I have to call in each of my php pages. Now I want to replace that old name with the new one using shell.
what iam using is this:
sed -i ās/old/new/gā *
but this is giving the following error:
sed: -e expression #1, char 1: unknown command:
How can I do this replacement?
sed -i.bak 's/old/new/g' *.php
to do it recursively
find /path -type f -iname '*.php' -exec sed -i.bak 's/old/new/' "{}" +;
There are probably less verbose solutions, but here we go:
for i in *; do sed -i 's/old/new/g' "$i"; done
Mind you, it will only work on the current level of the file system, files in subdirectories will not be modified. Also, you might want to replace * with *.php, or make backups (pass an argument after -i, and it will make a backup with the given extension).
this one is very simple, without for or loop, and takes care of any number or nested directories
grep -rl 'oldText' [folderName-optional] | xargs sed -i 's/oldText/newText/g'
You are using Unicode apostrophes (RIGHT SINGLE QUOTATION MARK - U2019) instead of ASCII (0x27) apostrophes around your sed command argument.
I know I'm really late but still:
find . -type f -name "*.php"|xargs sed -i 's/old/new/g'
perl -pi -e 's/old/new/g' *.php
For completeness, providing the OSX compatible version of the above accepted answer (to answer comment from #jamescampbell)
for i in *.php; do sed -i .orig 's/old/new/g' "$i"; done
This command creates .orig backup files.
Try this:
ls | grep "php" > files.txt
for file in $(cat files.txt); do
sed 's/catch/send/g' $file > TMPfile.php && mv TMPfile.php $file
done