Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using sed to replace just the first occurrence of a string #813

Closed
steophy opened this issue Jan 15, 2018 · 5 comments
Closed

using sed to replace just the first occurrence of a string #813

steophy opened this issue Jan 15, 2018 · 5 comments
Labels
question Question from a user (which may not require code/documentation changes to the project)

Comments

@steophy
Copy link

steophy commented Jan 15, 2018

Hello there

Node version (or tell us if you're using electron or some other framework):

v7.10.0

ShellJS version (the most recent version/Github branch you see the bug on):

v0.8.0

Operating system:

MacOs HighSierra 10.13.2

Description of the bug:

I'm using shelljs to perform a sed command and replace the whole line with a certain occurrence with another text. Here's the code that I'm using:


require('shelljs/global');

var new_version = process.argv[2];

sed('-i', /^.*version.*$/,
    '  "version": "'+new_version+'",',
    'package.json');

That version works but it replaces all the occurrence of "version". I have tried this code to replace only the first occurrence:

sed('-i', '0,/^.*version.*$/',

but that's not working at all: the file remains unchanged.

What am I missing?

@nfischer
Copy link
Member

shell.sed() doesn't change every match, it changes the first match per line (so this is working as intended). To demonstrate:

> shell.cat('file.txt');
hello world
hello hello world
> shell.sed(/hello/, 'bye', 'file.txt'); // first occurrence, for each line
bye world
bye hello world
> shell.sed(/hello/g, 'bye', 'file.txt'); // all occurrences, on all lines
bye world
bye bye world

To achieve what you want, you can try:

var contents = shell.cat('myfile');
var newContents = contents.replace(/(.|\n)*(my pattern)(.|\n)*/, 'replacement text');
(new ShellString(newContents)).to('myfile');

However, a more robust way to solve you specific problem would be:

var myPackage = require('package.json');
myPackage.version = 'new version number';
// pretty print with 2 space indent and trailing newline
var packageString = JSON.stringify(myPackage, null, 2) + '\n';
fs.writeFileSync('package.json', packageString);

@edgarechm
Copy link

Wait, wait.... so reading your last comment:

"To achieve what you want, you can try:

var contents = shell.cat('myfile');
var newContents = contents.replace(/(.|\n)(my pattern)(.|\n)/, 'replacement text');
(new ShellString(newContents)).to('myfile');"

Your solution to the issue is .... NOT USING "shell.sed" and use "contents.replace" instead? shell.sed doesn't work for this purpose?

@nfischer
Copy link
Member

shell.sed doesn't work for this purpose?

shell.sed() will replace the first occurrence of a pattern, for each line of input. It behaves like unix sed. If you want to only replace the very first occurrence, String.prototype.replace is already perfect, no library necessary.

@Madsn
Copy link

Madsn commented Jul 29, 2018

So, nothing like this is supported?
https://stackoverflow.com/a/13438118/605449

@nfischer
Copy link
Member

So, nothing like this is supported?
stackoverflow.com/a/13438118/605449

Currently, not supported (not opposed to it, however).

Also, that wouldn't necessarily be the right solution for the original post, but that shouldn't deter us from implementing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question from a user (which may not require code/documentation changes to the project)
Projects
None yet
Development

No branches or pull requests

4 participants