4

次のようなファイルでいっぱいのディレクトリがあります。

[Location]
state=California
city=Palo Alto

[Outlet]
id=23
manager=John Doe

次のように、ファイルごとに1行を出力する小さなスクリプトを書きたいと思います。

John Doe,Palo Alto

それ、どうやったら出来るの?私はいくつかのgrepとループを疑っています。これまでのところ、私は持っています:

#!/bin/bash
echo Manager,City > result.txt
for f in *.config
do
  cat "$f" | grep manager= >> result.txt
  cat "$f" | grep city= >> result.txt
done

しかし、grepは行全体を独自の行に返し、最初の=記号の後の部分だけが必要なので、それはもちろん不完全です。

4

3 に答える 3

2
echo Manager,City > result.txt

for f in *.config; do
    manager=$(awk -F= '$1=="manager" {print $2}' "$f")
    city=$(   awk -F= '$1=="city"    {print $2}' "$f")

    echo "$manager,$city"
done >> result.txt

awk -F=等号をフィールド区切り記号として使用し、目的の変数をチェックして ( $1)、それらの値を出力します ( $2)。コマンドの出力をキャプチャし、2 つの変数および$(cmd)に割り当てることができる文字列を生成します。$manager$city

于 2013-07-10T01:51:56.067 に答える
1

awk次のトランスクリプトに従って、1つのコマンドでこれを行うことができます。

pax> cat 1.config
[Location]
state=California
city=Palo Alto

[Outlet]
id=23
manager=John Doe

pax> cat 2.config
[Location]
state=Western Australia
city=Perth

[Outlet]
id=24
manager=Pax Diablo

pax> awk '
     /^city=/   {gsub (/^city=/, "", $0); city=$0}
     /^manager=/{gsub(/^manager=/, "", $0); print $0 "," city}
' *.config
John Doe,Palo Alto
Pax Diablo,Perth

これは、都市がマネージャーの前に来ることを前提としており、すべてのファイルに都市とマネージャーの両方があることに注意してください。これらの仮定が正しくない場合、awkスクリプトはもう少し複雑になりますが、それでも実行可能です。

その場合、次のようになります。

awk '
    FNR==1       {city = ""; mgr = ""}
    /^city=/     {gsub (/^city=/, "", $0); city = $0}
    /^manager=/  {gsub (/^manager=/, "", $0); mgr = $0}
                 {if (city!="" && mgr!=""){
                     print mgr "," city; city = ""; mgr = "";
                 }}
' *.config

これが行うことは、順序を無関係にすることです。各ファイルの先頭で都市変数とマネージャー変数を空の文字列にリセットし、関連する行が見つかった場合にのみそれらを保存します。すべての行の後、両方が設定されている場合は、それらを印刷してクリアします。

于 2013-07-10T02:02:33.463 に答える