質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

3161閲覧

sed コマンドを利用した置換処理について

l9uftn

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/10/08 08:31

編集2021/10/08 08:39

前提・実現したいこと

C++ のソースコードのプリプロセッサ命令の箇所のみを抽出して、ファイル毎に出力したい。

発生している問題・エラーメッセージ

sed コマンドを使って、「#」を含まない行を削除したいのですが、
扱いに慣れておらず、どのように表現すべきか悩んでいます。

該当のソースコード

例を以下に示します。

置換前 (sample.cpp)

cpp

1/* sample.cpp */ 2#include "sample.h" 3#define MACRO_A 4#ifndef MACRO_A 5#define MACRO_B 6#endif 7#define MACRO_C 8#undef MACRO_C 9/* 10#define MACRO_E 11*/ 12 13int main(void) 14{ 15 return 0; 16} 17

置換後 (sample.cpp.tmp)

cpp

1 2#include "sample.h" 3#define MACRO_A 4#ifndef MACRO_A 5#define MACRO_B 6#endif 7#define MACRO_C 8#undef MACRO_C 9 10#define MACRO_E 11 12 13 14 15

※置換前にコメント行は事前に削除しているため、
「/」と「/」と「//」は考慮しなくて構いません。

試したこと

下記条件で一致した行を削除しようとしましたが、
sed コマンドが否定先読みに対応していなかったため、諦めました。

置換前:^(?!\s*#).*$ 置換後:(入力無し)

以下のような利用を考えており、
どのように否定を表現するのかわからず、滞っています。

cd (cpp ファイルと h ファイルが格納されているフォルダ) for file in `find . -name '*.cpp' -or -name '*.h'`; do sed -i "s/(パターン)//g" $file # ここに記載するパターンに悩んでいます。 done

補足情報(FW/ツールのバージョンなど)

OS:Ubuntu20.04

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

itagagaki

2021/10/08 08:36

つまり ^\s*# にマッチする行を残したいわけですよね。 grep '^\s*#` じゃダメなんですか?
l9uftn

2021/10/08 08:58

grep で良かったです...
guest

回答3

0

sed -n -e "/^\s*#/p"

でしょうか。seds///g 以外にもいろいろなコマンドがあります。

投稿2021/10/08 08:46

int32_t

総合スコア21695

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

l9uftn

2021/10/08 09:00

勉強になります。 sed でもマッチした行のみ出力すれば、対応できたということですね。
guest

0

ベストアンサー

斜め上の回答ですみません。
sedを使わねば,と難しく考え過ぎではないかと思います。

例えば正規表現を使ったgrepであるegrepコマンド(あるいはgrep -E)を使って

bash

1egrep '^#.*' sample.c

とかで実現できるのではないかと思います。

投稿2021/10/08 08:39

ujimushi_sradjp

総合スコア2152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

l9uftn

2021/10/08 08:44 編集

知見が無いので教えていただきたいのですが、 こうすると、期待する出力が得られるものなのでしょうか。 egrep '^#.*' sample.c > sample.c.tmp
l9uftn

2021/10/08 08:57

確認したところ期待する結果が得られていました。 ありがとうございました。
otn

2021/10/08 10:02

grep '^#' だけでいいですね。 .* は不要です。 egrepである必要も無いです。まあ、「grepは使わず常にegrepを使う」という方針もありでしょうけど。
guest

0

# で始まらない行の削除は '/^[^#]/d'、空行の削除は '/^$/d' なので、
sed -i '/^[^#]/d;/^$/d' $file でよいのではないでしょうか?

投稿2021/10/09 03:27

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問