2

string で区切られたファイルのリストを含む変数があります_NEWLINE_。各ファイルが別々の行になるように、その変数をファイルに出力する必要があります。秘訣は、FreeBSD と Solaris で動作する必要があることです。

これは私が今試していることです:

echo "lib/alarms-1.2/priv/snmp_conf/agent.conf: lib/alarms/priv/snmp_conf/agent.conf_NEWLINE_lib/alarms-1.2/priv/snmp_conf/agent.conf.src: lib/alarms/priv/snmp_conf/agent.conf.src_NEWLINE_lib/alarms-1.2/priv/snmp_conf/community.conf: lib/alarms/priv/snmp_conf/community.conf" | sed 's|_NEWLINE_|\'$'\n|g'

これは、FreeBSD と Solaris のシェルで動作します。しかし、Solaris で GNUmakefile を実行すると、次のようになります (各行の末尾に $ があることに注意してください)。

lib/alarms-1.2/priv/snmp_conf/agent.conf: lib/alarms/priv/snmp_conf/agent.conf$
lib/alarms-1.2/priv/snmp_conf/agent.conf.src: lib/alarms/priv/snmp_conf/agent.conf.src$
lib/alarms-1.2/priv/snmp_conf/community.conf: lib/alarms/priv/snmp_conf/community.conf$

sed から削除する\'$'と、Solaris では動作しますが、FreeBSD では動作しません。メイクファイルが実行されるシステムに応じて、使用するバージョンを伝える方法があるのでしょうか?

編集: bobbogo によって提案された解決策のおかげで、望ましい結果を提供し、FreeBSD と Solaris の両方で動作しているように見える模範的なメイクファイルを作成しました。

one-line := lib/alarms-1.2/priv/snmp_conf/agent.conf: lib/alarms/priv/snmp_conf/agent.conf_NEWLINE_lib/alarms-1.2/\
priv/snmp_conf/agent.conf.src: lib/alarms/priv/snmp_conf/agent.conf.src_NEWLINE_lib/alarms-1.2/priv/snmp_conf/comm\
unity.conf: lib/alarms/priv/snmp_conf/community.conf

many-lines := { echo '$(subst _NEWLINE_,' && echo ',${one-line})'; }

.PHONY: all
all:
  $(shell $(many-lines) > test.txt)
4

4 に答える 4

1

\nこの回答で述べられているように定義することを含め、多くの異なる解決策を試しました: Makefile'foreach'ループに改行を追加します

本当の問題は、echoプラットフォーム間でのコマンドの実装に一貫性がないことと、デフォルトで、をmake使用してシェルコマンドを呼び出すという事実ですsh。これ自体は非常に柔軟性がありません。

私はこの答えのおかげでより良い方法を見つけました:直接呼び出されたときとシェルスクリプトを介して呼び出されたときの「echo-e」

より良い方法は、printf代わりに使用することですecho

出力ファイルの別々の行に入る部分を区切る\n代わりに、文字列を作成します。_NEWLINE_

some_string = lib/alarms-1.2/priv/snmp_conf/target_params.conf: lib/alarms/priv/snmp_conf/target_params.conf\nlib/alarms-1.2/priv/snmp_conf/community.conf: lib/alarms/priv/snmp_conf/community.conf\n

次に、makefileで次のように単純に出力します。

@printf "$(some_string)" >> $(some_file)

FreeBSDとSolarisの両方で動作します。

于 2013-02-08T00:01:28.767 に答える
1

これが GNU make の場合は、すべて make で行います。

one-line := lib/alarms-1.2/priv/snmp_conf/agent.conf: lib/alarms/priv/snmp_conf/agent.conf_NEWLINE_lib/alarms-1.2/priv/snmp_conf/agent.conf.src: lib/alarms/priv/snmp_conf/agent.conf.src_NEWLINE_lib/alarms-1.2/priv/snmp_conf/community.conf: lib/alarms/priv/snmp_conf/community.conf

define \n


endef

many-lines := $(subst _NEWLINE_,${\n},${one-line})

${many-lines}、あなたが望むものだけがあります。厄介なことに、シェルラインで使用するのは非常に困難です。これを行う場合:

tgt:
    echo '${many-lines}'

make は、行ごとに個別のシェルを呼び出します。最初のシェル呼び出しでは、ペアが解除され、エラーで終了します。'

.ONESHELL:
tgt:
    echo '${many-lines}'

侵襲的な方法で機能します。適切な修正は、 の各行に${many-lines}有効な sh 構文があることを確認することです。次のような一口:

echolines = $(subst ${\n},'${\n}echo ',echo '${many-lines}')
.PHONY: aa
aa:
    $(call echolines,${many-lines})

おいおい。

于 2013-02-11T14:41:45.017 に答える
0

免責事項:私はSolarisまたはFreeBSDの経験がありません...とにかくここに行きます。

makeでは、$(patsubst pattern、replacement、text)を使用してパターンを置き換えることができます。これを試して...

FILENAMES := "lib/alarms-1.2/priv/snmp_conf/agent.conf: lib/alarms/priv/snmp_conf/agent.conf_NEWLINE_lib/alarms-1.2/priv/snmp_conf/agent.conf.src: lib/alarms/priv/snmp_conf/agent.conf.src_NEWLINE_lib/alarms-1.2/priv/snmp_conf/community.conf: lib/alarms/priv/snmp_conf/community.conf"

.PHONY: all

all:
    @echo $(patsubst _NEWLINE_,${\n},$(FILENAMES))
于 2013-02-07T20:29:26.790 に答える
0

別の方法として、最初のアプローチがうまくいくと思います。$それを「エスケープ」するために2倍にするだけです。

sed 's|_NEWLINE_|\'$$'\n|g'
于 2013-02-08T02:29:30.000 に答える