awkコマンドを使用してn〜mフィールドを消去する方法は?

awkコマンドを使用してn〜mフィールドを消去する方法は?

AWKを使って次の問題を解決したいと思います。

sedやPerlのような言語を使って他のソリューションを実装することができれば、それにも感謝します。

入力は次のとおりです。

U,N,UNIX,000,A,5
N,P,SHELL,111,B,6
I,M,UNIX,222,C,7
X,Y,BASH,333,D,8
P,R,SCRIPT,444,E,9

私が望む出力は次のとおりです。

U,N,,,A,5
N,P,,,B,6
I,M,,,C,7
X,Y,,,D,8
P,R,,,E,9

また注:1行あたりのフィールドの総数がわかりません。フィールド3と4は空にしておく必要があることだけを知っています。

答え1

コマンドからnからmまでのすべてのフィールドを比例的に空にするには、awk値をハードコーディングしないでください。 「for」ループを使用する必要があります。

awk 'BEGIN { FS = ","; OFS = ","} {for (i = 3; i <= 4; i++) { $i = "" }; print}' inputfile

他の範囲を消去したい場合は、上記のコードで「3」と「4」の値を調整してください。


説明する:

BEGIN { ... }ブロックは、ファイル内のすべての行を表示する前に処理されます。

OFS出力フィールド区切り文字を設定し、入力フィールド区切りFS文字を設定します。私たちはそれらがカンマになりたいのです。

ループはforC構文と同じです。この場合は、3と4に対して次のことを行います{ code block }i

$iこれはシェル構文とはまったく異なることに言及する価値があります。シェルスクリプトで$変数値を拡張するには、変数名の前にプレフィックスを付ける必要があります。 in.inawk自体はその値(この場合は3または4)にawk展開され、その後に数値表現が続きます。i$大地その番号の位置から。したがって、2番目のフィールドは空の文字列に$i = ""設定されます。i

その後、print引数のないコマンドはデフォルトで行全体を印刷します。デフォルトでは、前のコマンドで区切られた行と前のコマンドで変更された行のすべてのフィールドがインポートされ、すべて印刷され、改行文字で区切られ、最後にFS改行文字が付けられます。OFS


対応するより短いコマンド:

上記のコマンドがスクリプトに含まれている場合は、最も明確で拡張しやすいコマンドだと思います。何をしているのかとても明確で読みやすいです。また、通話を使用または切り替えるときにawk自動的に実行できない操作は、変更なしでスタンドアロンスクリプトに分割できます。 (もちろんこれが使わないべき理由ではありません。注意するだけです。)-v-Fawk

特にワンタイム使用の場合は、以下を使用します。

awk -F, -v OFS=, '{for (i = 3; i <= 4; i++) { $i = "" }; print}' inputfile

スイッチ設定-Fの値ですFS。このスイッチを使用すると、コマンドラインで変数の値を設定できます-vawk

より一般的には、このスイッチはシェル変数をawk変数として渡し、コマンドラインオプションを使用してスクリプトファイルから抽出されたスタンドアロンスクリプトの実行時の動作を変更するのに役立ち-vます。-v myawkvar="$myshellvar"awk-f scriptname

答え2

</path/to/in_file awk -v 'FS=,' -v 'OFS=,' '{$3=$4=""; print}'

説明する

  • </path/to/in_file:ファイルを標準として読み込みます。
  • -v 'FS=,' -v 'OFS=,':ファイル区切り記号と出力ファイル区切り記号をに設定します,
  • '{$3=$4=""; print}':3番目と4番目のフィールドを空白に設定し、行全体を印刷します(略語:ジェイソン・ライアン)。

答え3

sed 's/\([^,]*,\)\{2\}/,,/2' <in >out

U,N,,,A,5
N,P,,,B,6
I,M,,,C,7
X,Y,,,D,8
P,R,,,E,9

これにより、コンマで区切られた2つの連続したフィールドセットの2番目のエントリが2つのカンマで置き換えられます。

次のようにすることもできます。

sed 's/[^,]*//4;s///3' <in >out

...カンマ以外の文字シーケンスの4番目と3番目のエントリを何も置き換えません。

@Wildcardのように拡張可能なループを使用してください。

sed -e:t -e'/\n\{2\}/!s/\(\n*\)[^,]*./\n\1/3;/\n$/!tt' -e's///;y/\n/,/'

...または...

sed -e:t -e's/\n$//;s/\n/&/2;to'  \
    -e's/\(\n*\)[^,]*./\1\n/3;tt' \
    -e:o -ey/\\n/,/

...どこ3ブランキングを開始するフィールド番号。,区切り記号です。2すべて空にするフィールドの数。

どのように書いたのか...

sed "$script" <<""
U
N,P
I,M,UNIX
X,Y,BASH,333
P,R,SCRIPT,444,E,9

U
N,P
I,M,
X,Y,,
P,R,,,E,9

...代わりにリテラル改行文字を使用する必要があるかもしれませんがn.../\1\n/3

答え4

Perlを使用できます。

perl -F, -lane '@F[2,3]=""; print join ",", @F'

これは-a自動分割を使用し、-Fカンマをフィールド区切り文字として使用します。-nSTDINを行ごとに繰り返します。次に、-eフィールド2と3を置き換えるスクリプトを指定し(Perlは最初から始まり)、結果を印刷します。

-l行末を暗黙的に削除して追加します。

関連情報