次の形式があります。
983243 woiewewrsadhjf 234
093111 srewdslkjfdgdsdsf 111
sedを使用して3番目のフィールドからテキストのすべてのインスタンスを取得し、そのインスタンスのみを変更し、他の3番目のフィールドを変更しないことはできますか?したがって、3番目のフィールドで111を検索すると、111を含む3番目のフィールドはすべて別のテキストに変更され、他の3番目のフィールド(234など)はそのまま残ります。
可能であれば、コマンドがどのように構成されているかを理解できるように、このソリューションを分析できますか?私は学ぶためにここにいます。
答え1
これが必須ではない場合、解決策sed
は次のとおりですawk
。
awk '$3=="111"{$3="othertext"}1' input.txt
各行に対して、3番目のフィールド(デフォルトではスペースで区切られた文字グループとして識別されます)が同じであることを確認し111
、そうである場合はに設定しますothertext
。入力データが異なる区切り記号(例)を使用している場合は、コマンドラインオプション(例)を使用して指定する必要がTAB
あります。-F
awk -F'\t' '....'
1
ルールブロックの外側({ ... }
または実際に「true」/ 0ではないと評価されるすべての条件)は、すべての修正を含むawk
現在の行を印刷するように指示します。これにより、変更する必要のない行が「現状のまま」印刷されます。
注:個々のフィールドで変更する必要がある行は、内部的に単一のスペースに設定されたawk
変数として格納されている「出力フィールド区切り文字」を使用して再構成されます。OFS
これは通常問題ではありませんが、列が複数のスペースで区切られている場合、これらの区切り文字は(デフォルトでは)次のように解釈されます。シングル変更されたフィールド区切りとして出力に行が表示されるように区切り記号を入力します。
答え2
フィールドはsed
図のように処理されます。まず、空白以外の3番目のブロックを、パターンスペースに存在しないことが知られている文字(レコード区切り文字など)で分離して表示します\n
。その後、交換が成功した場合、=> 3番目のフィールドに111があります。それ以外の場合は改行文字を削除します。
私たちはGNU sed
拡張正規表現フラグをオンにして使用しています。-E
$ sed -Ee '
s/\S+/\n&\n/3
s/\n111\n/otherwise/
s/\n//g
' file
Posixly私たちはこれを行います:
$ sed -e '
s/[^[:space:]]\{1,\}/\
&\
/3
s/\n111\n/otherwise/
s/\n//g
' file
答え3
echo '093111 srewdslkjfdgdsdsf 111' | sed 's/\(.*\) \(.*\) \(111\)/\1 \2 othertext/'
これがあなたが望むものです。
検索中のテキスト(この例では111)には、または\
同じ特殊文字は含まれていません。このような場合は脱出する必要があります。.
*
説明する
.
すべての文字と一致します。
*
前の原子のゼロ個以上の繰り返しを示します。
したがって、文章を書くとき、.*
すべての文字シーケンスを一致させます。ほとんどの場合、sedは貪欲です。つまり、可能な限り最大のシーケンスと一致しようとします。ただし、次の文字はスペースである必要があるため、.*
スペースを見つけた場合は一致が完了します。
デフォルトの正規表現(sedのデフォルト)を使用すると、およびを使用して\(
異なる\)
原子を分離できます。私たちはそれを使って3つの原子にラベルを付けます。
命令の第2の部分は\n
「n位置の原子」を意味する。最初と2番目を使用しますが、3番目は必要なテキストに置き換えます。
注:フィールド(スペースで区切り)を操作するときにawkを使用する方が簡単です。
echo '093111 srewdslkjfdgdsdsf 111' | awk '{if ($3 == "111") $3 = "othertext"; print}'