バッチテキスト修正スクリプトの作成

バッチテキスト修正スクリプトの作成

私はかなり大きなファイルに対して簡単なテキスト操作をしようとすることがよくあります。さまざまなUnixテキスト修正ツールの1つを使用してスクリプトを作成する方法があるはずですが、正確にはどうなるかわかりません。

具体的な例として、次のようなソースコードがあるとします。

foo1 = undefined
foo2 = undefined
foo3 = foobar 7
foo4 = undefined

私はこれを次のように変更したいと思います:

foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"

それ良いこの移行を自動化する方法は明らかです。きっと簡単にできると思います。プログラムを書く実際のプログラミング言語ですが、これを行うことができるいくつかのコマンドラインツールがあります。 (?)

もっと複雑な例として、どうすればいいですか?

foo=ABC
bar=DEF
baz=GHI
foo=123
bar=456
baz=789

入力する

Magic(ABC, DEF, GHI);
Magic(123, 456, 789);

より一般的には、これらの変換を実行するにはどのツールを使用する必要がありますか?それがsed、それともawk、それとも…?

答え1

具体的な状況によって異なります。最初の例は、またはを使用してsed解決できますawk。たとえば、次のようにしますawk

$ awk '
/undefined/ {printf "%s = error \"%s\"\n", $1, $1; next}
{print}
' input

次を生成します。

foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"

または以下を使用してくださいsed

sed '
  /undefined/ s/\([^ ]*\) =.*/\1 = error "\1"/
' input

2番目の例は、awkPerlやPythonなどの高度な言語を使用すると簡単に実行できます。繰り返しますがawk

awk '
{
    split($0, parts, "=")
    items[i++] = parts[2]
}
i%3 == 0 {
    printf "Magic(%s, %s, %s)\n", items[0], items[1], items[2]
    i=0
}

' input

次を生成します。

Magic(ABC, DEF, GHI)
Magic(123, 456, 789)

もっと一般的に言えば…一般的な答えを出すことができるかもしれません。これは、実際に達成したい特定のタスクによって異なります。いったん出たらawkプログラムを書く実際のプログラミング言語したがって、Perl、Python、Rubyなどの高度なツールがより強力であるという理由だけでこれを避けてはいけません。

答え2

sed簡単なテキスト操作に適しています。通常は1行編集ですが(かなりの努力をかけて)、複数行を処理することもできます。全体的に、sed変数と算術計算の欠如はかなり制限されていますが、それにもかかわらず、多くの状況で最も簡単な解決策を提供します。

awk単純で複雑なテキスト操作や数値計算には適していますが、他の操作には適していません。

最初の例は次のとおりです。

sed -E 's/^([^ ]+) = undefined$/\1 = error "\1"/' file1
awk '$3=="undefined"{ $3="error \"" $1 "\"" } {print $0}' file1

2番目の例では、=に基づいています。価値すべて大文字またはすべて数字です。また、Magic以外のすべての行をグループ化します(削除するにはout[0]文のみを削除します)。

awk -F'=' 'BEGIN{ # split regular expressions, using `x7F` as delimiter (or any char not in the regex)  
                  n=split("^[A-Z]+$" "\x7F" "^[0-9]+$",rx,"\x7F") 
           } 
           { for( i=1;i<=n;i++ ){
                 if( $2 ~ rx[i] ){ 
                     out[i]=out[i] sprintf( (out[i] ?", " :"") "%s", $2)
                     break 
             }   } 
             if( i>n ) out[0]=out[0] $0 RS # non-matching lines 
           }
           END{ printf out[0]
                for( i=1;i<=n;i++ ){ print "Magic(" out[i] ")" }
           }' file2

答え3

Perlは、強力なテキスト操作(検索、vi(1)スタイルの正規表現の置き換え)に基づいて構築された(かなり「一般的な」)プログラミング言語であるため、Perlを使用します。しかし、多くの人は私が異端者だと思い、Pythonを使用します。どちらもすべてのLinuxディストリビューションで配布され、どちらも適切なWindows実装を備えています(Macでも同様であると確信しています)。 Pythonの利点は、Fedoraなどの管理ツール用のほとんどのGUIを構築するために使用できるため、すでにインストールされている必要があることです。

awk(1)どちらもsed(1)強力なツールですが、一部は専門化されています。

関連情報