0

I hope this fits in here (I guess it would also be a match for Stack Overflow, since I'm using a nodeJS module) but basically I'm trying to add // @ts-nocheck \n to the beginning of every file with the .ts file extension.

I'm using ShellJS which, unfortunately, does not appear to support line addressing as per this GitHub issue.

Since sed -i 1i is not supported, what would be a good alternative?

Note that awk is also not available inside ShellJS.

grep, cat, head, tail, sort, echo and uniq are the only available text manipulation commands.

2
  • Not even printf? Only echo? And do you want a literal \n there or do you want an actual newline? Commented Nov 28, 2022 at 17:50
  • An actual newline. Yea. Not even printf. I'm open to nodeJS recommendations, too. I think using ShellJS exclusively is opening me up for a world of pain. Commented Nov 28, 2022 at 18:13

2 Answers 2

1

You could do something like this, assuming you can have a shell loop:

for file in *ts; do
    echo "// @ts-nocheck \n" | cat - "$file" > newfile
    mv newfile "$file"
done

If you want an actual newline and not a literal \n, just remove the \n from the command above.

5
  • I thought about this before. Unfortunately, I need to prepend the comment to several hundred files so this would be too costly and prone to race conditions. Commented Nov 28, 2022 at 18:14
  • @user237251 costly, only in terms of time taken, it isn't computationally intense. But yes, it will be slow but them's the requirements you've imposed if you need to do it using this very limited toolset :/. I don't see the race condition though, where is that? Commented Nov 28, 2022 at 18:16
  • I'm not sure. I just can see potential errors if a file isn't properly closed before the next one is being opened. But yea. Time taken will be too immense so it's a no-go anyways. Guess I'll need to look into a native nodeJS solution or another module. Commented Nov 28, 2022 at 18:22
  • 1
    @user237251 all files will be closed correctly unless there is a huge bug in this shell you're using that would affect pretty much everything. This is a very basic, standard operation. Can't you just run a system call and use perl or awk or even the normal, system sed? Commented Nov 28, 2022 at 18:26
  • Using system calls or shelling out would beat the purpose of the whole exercise (I inherited a mess of Bash bootstrap scripts I'm porting to nodeJS). Anyhow. I think I can answer my own question now. I found a solution to do it with nodeJS. Not exactly the "Unix way" but it works for my use-case. Commented Nov 28, 2022 at 18:41
0

I think I found a solution.

Based on this Stack Overflow, I came up with code that circumvents the lackluster POSIX support in ShellJS by using the native NodeJS API

function nocheck() {
  console.log("👉 Adding @ts-nocheck to all .ts files ...");
  let nocheck = "// @ts-nocheck\n";
  let files = shell.find("**/*.ts");
  files.forEach((element) => {
    let data = readFileSync(element);
    let fd = openSync(element, "w+");
    writeSync(fd, nocheck, 0, nocheck.length, 0);
    writeSync(fd, data, 0, data.length, nocheck.length);
    close(fd, (err) => {
      if (err) throw err;
    });
  });
}
1
  • Is the writeSync() method guaranteed to write the whole buffer, or could it write a bit, return, and then allow you to call it again to write the next bit, using the returned value from the last call as an offset? I'm thinking of solutions that would still be valid for really large files. If you are making assumptions, you need to specify these in the answer. I see you are catching an error at the end. What is the state of the data on disk if that happens? Commented Nov 28, 2022 at 19:39

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.