以下を取るsed
(またはその両方)を書く方法:awk
echo '1 aa 2 2 3 bb 5 bb 2 5' | sed/awk ...
そして、n番目の文字列だけを変更しますか?例えば第三登場か2
、第二登場かbb
?
したがって、予想される出力は次のようになります(たとえば、2番目の項目を置き換える場合)bb
。replaced
1 aa 2 2 3 bb 5 replaced 2 5
入力文字列、代替文字列はn
任意の入力にすることができます。
答え1
sed
2回目の発生を変更するために使用されます。bb
$ sed 's/bb/new-bb/2' file
1 aa 2 2 3 bb 5 new-bb 2 5
または 2 の 3 番目の発生を変更します。
$ sed 's/2/12/3' file
1 aa 2 2 3 bb 5 bb 12 5
答え2
1行目のn番目の発生位置を変更するには、sed
構文は次s/pattern/replacement/3
のとおりです。@HatLessはすでにデモしています。。
入力全体のnperl
番目の発生を変更するには、次のようにします。
perl -pse 'if($n>0) {s{pattern}{--$n ? $& : "replacement"}ge}' -- -n=3
答え3
一緒にawk
できること:
awk -v str='bb' -v pos=2 -v rplc='newBB' '
{
strPos=0
for(i=1; i<=NF; i++)
if($i==str && (++strPos==pos) ) { $i=rplc; break }
}1' infile
出力:
1 aa 2 2 3 bb 5 newBB 2 5
注:上記はフィールド区切り文字として1文字のみを想定しています(デフォルト:スペースまたはタブ)。それ以外の場合は、連続したフィールド区切り文字を1つに圧縮するか、awkが各単一フィールド区切り文字と個別に一致するように強制することができます(したがって、FSは正規表現として強制する必要があります)。パターン):
awk -F'[\t]' -v OFS='\t' -v str='bb' -v pos=2 -v rplc='newBB' '
{
strPos=0
for(i=1; i<=NF; i++)
if($i==str && (++strPos==pos) ) { $i=rplc; break }
}1' infile
注:\t
フィールド区切り文字が空白文字の場合は、空白文字に変更してください。
入力全体でn番目の項目を変更するには(ただし、フィールド区切り文字はタブであると仮定します):
awk -F'[\t]' -v OFS='\t' -v str='bb' -v pos=2 -v rplc='newBB' '
strPos!=2{
for(i=1; i<=NF; i++)
if($i==str && (++strPos==pos) ) { $i=rplc; break }
}1' infile
答え4
1つのコマンドで両方の操作を実行できますsed
。
echo "1 aa 2 2 3 bb 5 bb 2 5"|sed -e "s/2/kop/3" -e "s/bb/pp/2"
2
このコマンドは、3番目の発生項目をwithにkop
、2番目の発生項目をbb
withに置き換えますpp
。