Skip to content

Commit bccf620

Browse files
committed
feat(sed): support multiple file names
fixes #231. Semantics are like unix sed.
1 parent b170d20 commit bccf620

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaS
331331
those returned by `cat`, `grep`, etc).
332332

333333

334-
### sed([options,] search_regex, replacement, file)
334+
### sed([options,] search_regex, replacement, file [, file ...])
335+
### sed([options,] search_regex, replacement, file_array)
335336
Available options:
336337

337338
+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
@@ -343,7 +344,7 @@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
343344
sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
344345
```
345346

346-
Reads an input string from `file` and performs a JavaScript `replace()` on the input
347+
Reads an input string from `files` and performs a JavaScript `replace()` on the input
347348
using the given search regex and replacement string or function. Returns the new string after replacement.
348349

349350

src/sed.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ var common = require('./common');
22
var fs = require('fs');
33

44
//@
5-
//@ ### sed([options,] search_regex, replacement, file)
5+
//@ ### sed([options,] search_regex, replacement, file [, file ...])
6+
//@ ### sed([options,] search_regex, replacement, file_array)
67
//@ Available options:
78
//@
89
//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
@@ -14,9 +15,9 @@ var fs = require('fs');
1415
//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
1516
//@ ```
1617
//@
17-
//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input
18+
//@ Reads an input string from `files` and performs a JavaScript `replace()` on the input
1819
//@ using the given search regex and replacement string or function. Returns the new string after replacement.
19-
function _sed(options, regex, replacement, file) {
20+
function _sed(options, regex, replacement, files) {
2021
options = common.parseOptions(options, {
2122
'i': 'inplace'
2223
});
@@ -32,19 +33,32 @@ function _sed(options, regex, replacement, file) {
3233
if (typeof regex === 'string')
3334
regex = RegExp(regex);
3435

35-
if (!file)
36-
common.error('no file given');
36+
if (!files)
37+
common.error('no files given');
3738

38-
if (!fs.existsSync(file))
39-
common.error('no such file or directory: ' + file);
39+
if (typeof files === 'string')
40+
files = [].slice.call(arguments, 3);
41+
// if it's array leave it as it is
4042

41-
var result = fs.readFileSync(file, 'utf8').split('\n').map(function (line) {
42-
return line.replace(regex, replacement);
43-
}).join('\n');
43+
files = common.expand(files);
4444

45-
if (options.inplace)
46-
fs.writeFileSync(file, result, 'utf8');
45+
var sed = [];
46+
files.forEach(function(file) {
47+
if (!fs.existsSync(file)) {
48+
common.error('no such file or directory: ' + file, true);
49+
return;
50+
}
4751

48-
return common.ShellString(result);
52+
var result = fs.readFileSync(file, 'utf8').split('\n').map(function (line) {
53+
return line.replace(regex, replacement);
54+
}).join('\n');
55+
56+
sed.push(result);
57+
58+
if (options.inplace)
59+
fs.writeFileSync(file, result, 'utf8');
60+
});
61+
62+
return common.ShellString(sed.join('\n'));
4963
}
5064
module.exports = _sed;

test/sed.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,15 @@ assert.ok(shell.error());
2121
shell.sed(/asdf/g, 'nada'); // too few args
2222
assert.ok(shell.error());
2323

24-
assert.equal(fs.existsSync('/asdfasdf'), false); // sanity check
25-
shell.sed(/asdf/g, 'nada', '/asdfasdf'); // no such file
24+
assert.equal(fs.existsSync('asdfasdf'), false); // sanity check
25+
shell.sed(/asdf/g, 'nada', 'asdfasdf'); // no such file
26+
assert.ok(shell.error());
27+
28+
// if at least one file is missing, this should be an error
29+
shell.cp('-f', 'resources/file1', 'tmp/file1');
30+
assert.equal(fs.existsSync('asdfasdf'), false); // sanity check
31+
assert.equal(fs.existsSync('tmp/file1'), true); // sanity check
32+
shell.sed(/asdf/g, 'nada', 'tmp/file1', 'asdfasdf');
2633
assert.ok(shell.error());
2734

2835
//
@@ -74,4 +81,24 @@ var result = shell.sed('l*\\.js', '', 'resources/grep/file');
7481
assert.ok(!shell.error());
7582
assert.equal(result, 'alphaaaaaaabeta\nhowareyou\nalphbeta\nthis line ends in\n\n');
7683

84+
shell.cp('-f', 'resources/file1', 'tmp/file1');
85+
shell.cp('-f', 'resources/file2', 'tmp/file2');
86+
87+
// multiple file names
88+
var result = shell.sed('test', 'hello', 'tmp/file1', 'tmp/file2');
89+
assert.equal(shell.error(), null);
90+
assert.equal(result, 'hello1\nhello2');
91+
92+
// array of file names (and try it out with a simple regex)
93+
var result = shell.sed(/t.*st/, 'hello', ['tmp/file1', 'tmp/file2']);
94+
assert.equal(shell.error(), null);
95+
assert.equal(result, 'hello1\nhello2');
96+
97+
// multiple file names, with in-place-replacement
98+
var result = shell.sed('-i', 'test', 'hello', ['tmp/file1', 'tmp/file2']);
99+
assert.equal(shell.error(), null);
100+
assert.equal(result, 'hello1\nhello2');
101+
assert.equal(shell.cat('tmp/file1'), 'hello1');
102+
assert.equal(shell.cat('tmp/file2'), 'hello2');
103+
77104
shell.exit(123);

0 commit comments

Comments
 (0)