私はコードを持っています:
1 /**
2 a b c
3 **/
4 int main() {
5 int x;
6 if ( condition) {
7 return x;
8 }
9 }
行7と同様に、トークンまたは文字列の間の複数のスペースを単一のスペースに変更する必要がありますが、コメント(行2)またはコードの前のタブは影響を受けてはいけません。したがって、出力は次のようになります。
1 /**
2 a b c
3 **/
4 int main() {
5 int x;
6 if ( condition) {
7 return x;
8 }
9 }
'tr'を試しましたが、~$ tr -s " " < file
2行が変更され、5行から8行から先行タブ文字が削除されました。を使用して実行できますかsed
?
答え1
どのくらい行くのでしょうか?
sed -rn '\#/\*\*#,\#\*\/*# {p;b}; s/([^ ]) +/\1 /g; p' file
わかりますか?変更されていないコメント行を印刷し(ただし、同じ行のコメントのオン/オフを処理できない)、スクリプトの残りの部分をスキップします。コメントアウトされていない行の場合は、空白以外の文字に続く複数の空白(したがって範囲外の行のインデント)を単一の空白に圧縮します。
答え2
最後に、これは私にとって効果的でした。
sed -i 's/\([a-zA-Z]\+\)\( *\)\([a-zA-Z]\+\)/\1 \3/g' $1
答え3
使用幸せ(以前のPerl_6)
~$ raku -pe 's/^ [\d+ " "?] \t* \H+? <(" " ** 2..*)> / /;' file
#OR
~$ raku -pe 's/^ [\d+ " "?] \c[TAB]* \H+? <(\c[SPACE] ** 2..*)> / /;' file
上記のRakuコードは文字通りタブ(\t
or)\c[TAB]
とスペース(" "
or \c[SPACE]
)を区別します。
これらの-pe
フラグは自動印刷機能を使用して、入力からコードを1行ずつ実行します。正規表現は^
、文字列の先頭から数字を検索し、[\d+ " "?]
その後にゼロまたは1つの空白、その後にオプションのタブ文字、その後に(貪欲ではない)\H+?
1つ以上の水平でない空白文字、最後に 2..*
2つ以上の空白を検索します。 。<(
...キャプチャ)>
タグは、単一のスペースで置き換えられた最後の2つ以上のスペースを除いて、一致するすべてのエントリを削除します。
[\d+ " "?]
行番号がない場合、角かっこで囲まれたグループは省略されます。 1行に1つだけを置き換えるため、行の右端に複数の空白文字がある場合は、複数回実行する必要があります。
入力例:
1 /**
2 a\tb\tc
3 **/
4 int main() {
5\tint x;
6\tif ( condition) {
7\treturn x;
8\t}
9 }
出力例:
1 /**
2 a\tb\tc
3 **/
4 int main() {
5\tint x;
6\tif ( condition) {
7\treturn x;
8\t}
9 }
もちろん、上記の答えは、コメントブロックの文字が複数の空白ではなくタブで区切られていることに基づいています。おそらく最良の方法はそれある事前実行特にコメントブロックを変更してください。
~$ raku -pe 'state $ph; \
$ph = 1 if /^ "/**" \s* $/; \
$ph = 0 if /^ "**/" \s* $/; \
s:g/" " ** 4/\t/ if $ph == 1 ;' file
上記のコードは、コメントブロック内でのみ4つのスペースをタブ文字に置き換えます。各行が行番号で始まる場合は、[\d+ " "?]
2番目と3番目のステートメントの角かっこグループにもう一度追加してください。^
https://unix.stackexchange.com/a/701572/227738
https://docs.raku.org/言語/regexes
https://raku.org