次のようないくつかの「include」ステートメントで始まるファイルがあります。
include foo.xyz
include bar.xyz
do c
do d
ファイルfoo.xyz
にdo a
が含まれ、ファイルbar.xyz
にdo b
が含まれているとします。各include file.xyz
ステートメントをfile.xyz
のコンテキストに置き換えるスクリプトを作成するにはどうすればよいですか?次の出力になりたいです。
do a
do b
do c
do d
" sedを使用して文字列をファイルの内容に置き換えます "で解決策を試しましたが、ファイル名がハードコーディングされています。 include
引数に応じて、ファイル名を動的に生成したいと思います。
これはawkを使用した単純な再帰バージョンです。 PATHにスクリプトを作成する必要があります
#!/bin/bash
awk '
$1=="include" && NF>=2 {
system("'$0' " $2)
next
}
{print}' "$@"
ファイル名に特別な文字(スペースを含む)が含まれていないことを前提としています。 awkは最初のWordでインクルードをチェックし、スクリプトを呼び出して2番目のWordとして指定されたファイルを処理します。他の行が印刷されます。ここでの$0
はoutside awkの一重引用符であり、シェル$0
、つまりスクリプト名も同様であることに注意してください。
grep -n '^include ' yourfile |
sed -e 's/:[^ ]* /{ r /' \
-e 'G;s/.$/&b&}/' |
sed -nf - -ep yourfile
それはうまくいくはずです。 grep
はそれらを見つけますinclude行番号、最初のsed
はその出力を行番号固有の[num]{r fname\nb\n}
コマンドに変更し、2番目のsed
p
rintsは、最初のスクリプトの1つではないすべての行です。
{ for x in a b
do echo "do $x">"file$x.xyz"
echo "include file$x.xyz"
done; printf "do %s\n" c d
} >yourfile
cat yourfile
include filea.xyz
include fileb.xyz
do c
do d
これはサンプルを生成し、yourfileを表示します。
そしてこれは機能します:
grep -n '^include ' yourfile |
sed -e 's/:[^ ]* /{ r /' \
-e 'G;s/.$/&b&}/' |
sed -nf - -ep yourfile
do a
do b
do c
do d
もちろん、r
eadファイルは任意のサイズにすることができ、1行に制限されません。ただし、ファイル名自体は1行に制限されていますが、それ以外は多かれ少なかれ制限されていません(sed
によって異なります-古いseds
には任意の名前の長さの制限がありましたが、今日最も使用されているものはありません)。
cat $(grep '^include' file.txt | cut -d" " -f2); grep -v '^include' file.txt
最初のコマンドは、file.txt
のgrep
で始まる行、include
ファイル名の部分、次にcut
それをcat
します。
次のコマンドは、file.txt
のinclude
で始まる行を除くすべての行を出力します