sed 内联剥离注释

arc*_*ryx 2 bash sed text-processing

我有一个简单的 bash 脚本来从 js 文件中删除注释:

#!/bin/bash
sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' $1 >> stripped.js
Run Code Online (Sandbox Code Playgroud)

除了内联出现的注释外,这几乎完美无缺,例如

// file-to-be-stripped.js
...
...
const someVar = 'var' // this comment won't be stripped
// this comment will be stripped
Run Code Online (Sandbox Code Playgroud)

我错过了什么来去除内联评论?

更新:

真正奇怪的是,我使用在线 bash shell 启动了您的示例,并且它运行完美!但是,当我在本地运行完全相同的代码时,它不会剥离内联代码!?知道为什么/怎么会这样吗?我显然错过了一些东西……很奇怪。

这是我更新的代码:

我的脚本:stripper.sh

#!/bin/bash
sed -E -e 's:(\s+(//|#)|^\s*(//|#)).*$::; /^$/d' $1 > "stripped.${1}"
Run Code Online (Sandbox Code Playgroud)

我的测试文件:test.js

// testies one
const testies = 'two'
console.log(testies) // three
// testies FOUR!?
console.log('Mmmmm toast') // I won't be stripped of my rights!
Run Code Online (Sandbox Code Playgroud)

然后我执行:./stripper.sh test.js输出是:

const testies = 'two'
console.log(testies) // three
console.log('Mmmmm toast') // I won't be stripped of my rights!
Run Code Online (Sandbox Code Playgroud)

任何想法为什么只在本地运行完全相同的代码 sed 的整行注释但使用在线 bash 解释器运行它(不幸的是,我无法分享到我的 shell 的确切链接,因为它是一个有点。ly 链接,显然这是一个“不” .) 是否按预期工作?

Sté*_*las 6

POSIXly,你会这样做:

sed '
  s|[[:blank:]]*//.*||; # remove //comments
  s|[[:blank:]]*#.*||; # remove #comments
  t prune
  b
  :prune
  /./!d; # remove empty lines, but only those that
         # become empty as a result of comment stripping'
Run Code Online (Sandbox Code Playgroud)

对于 GNU,sed我们可以缩短为:

sed -E 's@[[:blank:]]*(//|#).*@@;T;/./!d'
Run Code Online (Sandbox Code Playgroud)

请注意,它会高兴地删除#things//things那些不喜欢评论:

const url = 'http://stackexchange.com';
x = "foo#bar";
Run Code Online (Sandbox Code Playgroud)

要忽略#,//内引号,您可以执行以下操作:

perl -ne 'if (/./) {
   s{\s*(?://|#).*|("(?:\\.|[^"])*"|'"'(?:\\\\.|[^'])*'"'|.)}{$1}g;
   print if /./} else {print}'
Run Code Online (Sandbox Code Playgroud)

在像这样的输入上:

#blah
// testies one
const testies = 'two';
console.log(testies) // three

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar" # comment
y = 'foo\'bar' # it's a comment
Run Code Online (Sandbox Code Playgroud)

它给:

const testies = 'two';
console.log(testies)

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar"
y = 'foo\'bar'
Run Code Online (Sandbox Code Playgroud)

(您可能需要适应这些文件的实际语言(我不知道 JavaScript 支持#作为注释,除了第一行以#!node.js开头))。