パターン交換のためのsedの使用[閉じる]

パターン交換のためのsedの使用[閉じる]

誰でもこの問題を解決する方法を提案できますか?ファイルがあり、一致する行に最初に表示されるパターンを動的値に置き換えたいとします。ここでのパターンはですas

ソースファイル:

a b c as aa as
as b d f aa sa
df as kf as df

ターゲットファイル:

a b c 1 aa as
2 b d f aa sa
df 3 kf as df

答え1

交換モードは毎回変わるので、これはおそらくもう少し奇妙なことです。

awk 'BEGIN { needle=1 } /as/ { $0=gensub( /as/, needle, 1, $0 ); needle=needle+1} { print } ' /path/to/input

上記は以下に適用されます。GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.4, GNU MP 6.1.0)

答え2

本当にsedを使用したい場合は、whileループ内で素敵に実行できます。

count=1;
while read line
    do sed 's/as/'"$count"'/1' <<< "$line";
    count=$((count+1));
done < source_file >> target_file

sed コマンド内で使用するために変数を適切に拡張するには、シェルに囲む''ペアが必要です。"$count"

短いです(Kusalanandaに感謝します):

while read line
    do sed 's/as/'"$(( ++count ))"'/1' <<< "$line";
done < source_file > target_file

パターンが見つかった場合にのみ増加させたい場合:

count=1;
while read line;
    do sed '/as/! {q100}; s/as/'"$count"'/1' <<< "$line";
    [[ "$?" -eq 0 ]] && (( ++count ));
done < source_file > target_file

答え3

そしてperl

$ perl -pe 'BEGIN{$n=1} s/as/$n++/e' file
a b c 1 aa as
2 b d f aa sa
df 3 kf as df

答え4

以下は、必要なタスクを実行する小さなPythonスクリプトです。

#!/usr/bin/env python
import sys
counter = 0
with open(sys.argv[1]) as fd:
    for line in fd:
        new_words = []
        words = line.strip().split()
        found = False
        for word in words:
            val = word
            if word == 'as' and not found:
                counter += 1
                found = True
                val = str(counter)
            new_words.append(val)

        print(" ".join(new_words))

そしてテストを実行するには:

$ ./substitute_dynamic_val.py input.txt                                                                                  
a b c 1 aa as
2 b d f aa sa
df 3 kf as df

関連情報