ファイルコンテンツの検索と置換

ファイルコンテンツの検索と置換

次のような "include" ステートメントで始まるファイルがあります。

include foo.xyz
include bar.xyz
do c
do d

ファイルfoo.xyzにが含まれてdo aいてファイルにがbar.xyz含まれているとします。各ステートメントをのコンテキストに置き換えるdo bスクリプトをどのように書くことができますか?私は次のような結果を得たいと思います。include file.xyzfile.xyz

do a
do b
do c
do d

頑張った」sedを使用して文字列をファイルの内容に置き換える「しかし、ファイル名はハードコードされています。パラメータに応じてファイル名を動的に生成したいと思いますinclude

答え1

これはawkを使った単純な再帰バージョンです。 PATHにスクリプトを生成する必要があります。

#!/bin/bash
awk '
$1=="include" && NF>=2 {
   system("'$0' " $2)
   next
}
{print}' "$@"

ファイル名に特殊文字(スペースを含む)がないとします。 awkは最初の単語が含まれていることを確認し、スクリプトを呼び出して2番目の単語として提供されたファイルを処理します。追加の行を印刷します。参考$0としてここに外部awkの場合は一重引用符、シェルの場合も同じです$0。つまり、スクリプト名です。

答え2

grep -n '^include ' yourfile |
sed  -e 's/:[^ ]* /{ r /'    \
     -e 'G;s/.$/&b&}/'       |
sed -nf - -ep       yourfile

それでは効果があるでしょう。grepそれを探してください含む1つ目は行番号に固有のコマンドsedで出力を変更し、2つ目は最初のスクリプトの1つではなくすべての行を印刷します。[num]{r fname\nb\n}sed p

{   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

これでサンプルが作成され表示されます。あなたのプロフィール

これは働きます:

grep -n '^include ' yourfile |
sed  -e 's/:[^ ]* /{ r /'    \
     -e 'G;s/.$/&b&}/'       |
sed -nf - -ep       yourfile

do a
do b
do c
do d

もちろん、eadrファイルのサイズは制限されず、1行に制限されません。ファイル名自体は1行に制限されていますが、それ以外にはやや制限はありません。(ユーザーによって異なりますsed。一部の古い名前にはランダムな名前sedsの長さの制限がありますが、今日使用されているほとんどはそうではありません。)

答え3

cat  $(grep '^include' file.txt | cut -d" " -f2); grep -v '^include' file.txt

最初のコマンドは、grepinで始まる行、ファイル名の部分、およびその行を使用します。includefile.txtcutcat

次のコマンドは、includein で始まる行を除くすべての行を印刷します。file.txt

関連情報