4

誰かがこのシナリオで私を助けてくれますか? 構成ファイル (Linux) 内で一意の文字列を検索し、行を上ってその行の末尾に文字列を追加するために使用できる SED または AWK コマンドを探しています。

例えば:

設定ファイル:

ホストグループを定義{
hostgroup_name http-urls ;
ホストグループエイリアスの HTTP URLの名前。グループ
メンバーの長い名前 domain1.com、domain2.com、domain3.com、
#MyUniqueString
}

上記の例では、SED または AWK を使用して#MyUniqeStringを検索し、 membersで始まる行を上に移動し、行末に「domain4.com」を追加します。

以下にこの質問を見つけましたが、最初にテキスト ファイルで文字列を検索し、1 行上に移動する必要があります。

Bash スクリプト: ファイルの特定の行の最後の文字にテキストを追加する

助言がありますか?

4

5 に答える 5

4

これは、次の方法で効果的に行うことができますed

ed yourfile <<-'EOF'
    /#MyUniqueString/ # Find the matching line
    - # Go up a line
    a # Append text
    domain4.com
    . # Stop appending
    .-1,.j # Join the line above with the appended line
    w # Write the line
EOF
于 2012-12-19T18:52:43.983 に答える
2

3つの異なるソリューションの比較

小さい、使用sed

sed -e ':a;N;/\n#MyUniqueString/{s/\n/ domain4.com\n/};H;s/\n.*$//;p;g;s/^.*\n//;ta;' config.file

これは次のように実行できます。

sed -e '
   :a;
    N;
    /\n#MyUniqueString/{
        s/\n/ domain4.com\n/
    };
    H;
    s/\n.*$//;
    p;
    g;
    s/^.*\n//;
    ta;
   ' config.file

プロファイリング:

time sed ':a;N;/\n#MyUniqueString/{s/\n/ domain4.com\n/};H;
                      s/\n.*$//;p;g;s/^.*\n//;ta;' config.file 
define hostgroup{
hostgroup_name http-urls ; The name of the hostgroup
alias HTTP URLs ; Long name of the group
members domain1.com, domain2.com, domain3.com, domain4.com
#MyUniqueString
}



real    0m0.010s
user    0m0.000s
sys     0m0.008s

なぜ純粋なbashではないのですか?

フォークがないため、これは非常に高速である可能性があります(構成ファイルbashが長すぎない場合):

readarray configFile < ./config.file
for ((i=${#configFile};i--;));do
    [[ "${configFile[i]}" =~ "#MyUniqueString" ]] && break
  done
configFile[i-1]+=" domain4.com"
printf "%s\n" "${configFile[@]//$'\n'/}"

によって実行されるプロファイリング:

time {
    readarray configFile < ./config.file
    for ((i=${#configFile};i--;));do
        [[ "${configFile[i]}" =~ "#MyUniqueString" ]] && break
      done
    configFile[i-1]+=" domain4.com"
    printf "%s\n" "${configFile[@]//$'\n'/}"
}

あげる:

define hostgroup{
hostgroup_name http-urls ; The name of the hostgroup
alias HTTP URLs ; Long name of the group
members domain1.com, domain2.com, domain3.com, domain4.com
#MyUniqueString
}

real    0m0.001s
user    0m0.000s
sys     0m0.000s

でテストするawk

time awk '{a[NR]=$0}/#MyUniqueString/{a[NR-1]=a[NR-1]" domain4.com"}END{for(i=1;i<=NR;i++)print a[i]}' config.file 
define hostgroup{
hostgroup_name http-urls ; The name of the hostgroup
alias HTTP URLs ; Long name of the group
members domain1.com, domain2.com, domain3.com, domain4.com
#MyUniqueString
}

real    0m0.009s
user    0m0.004s
sys     0m0.000s
于 2012-12-19T19:25:14.280 に答える
2

後方参照を使用した別の sed ソリューションは次のとおりです。

sed '{N; N; s/\(.*\)\n\(#MyUniqueString\)/\1domain4.com\n\2/g}' config.file
于 2012-12-19T19:32:32.513 に答える
1

この awk ソリューションでは、前の行のみが記憶されている必要があります

awk '
    /#MyUniqueString/ {prev = prev "domain4.com"} 
    NR > 1 {print prev}
    {prev=$0}
    END {print prev}
'
于 2012-12-19T20:54:05.270 に答える
1

このワンライナーを試してください:

awk '{a[NR]=$0}/#MyUniqueString/{a[NR-1]=a[NR-1]"domain4.com"}END{for(i=1;i<=NR;i++)print a[i]}' configFile

テスト

kent$  cat test.txt 
define hostgroup{
hostgroup_name http-urls ; The name of the hostgroup
alias HTTP URLs ; Long name of the group
members domain1.com, domain2.com, domain3.com,
#MyUniqueString
}

kent$  awk '{a[NR]=$0}/#MyUniqueString/{a[NR-1]=a[NR-1]"domain4.com"}END{for(i=1;i<=NR;i++)print a[i]}' test.txt 
define hostgroup{
hostgroup_name http-urls ; The name of the hostgroup
alias HTTP URLs ; Long name of the group
members domain1.com, domain2.com, domain3.com,domain4.com
#MyUniqueString
}
于 2012-12-19T18:46:15.090 に答える