Bash、ドットで区切られた文字列からIPを切り捨てる

Bash、ドットで区切られた文字列からIPを切り捨てる

いくつかの形式の結果があります。

10.3.2.1.in-addr.arpa name hostname

中間部分「.in-addr.arpa」を削除し、IPアドレスを1.2.3.10に変更したいと思います。単純なbash onelinerでこれを行うことはできますか?よろしくお願いします。これを数時間試してみましたが、少し停止しました。

答え1

そしてperl

perl -pe 's/(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/$4.$3.$2.$1/g' < input

標準に対応するよりも簡潔で読みやすいですsed

d='\([0-9]\{1,\}\)'
LC_ALL=C sed "s/$d\.$d\.$d\.$d\.in-addr\.arpa/\4.\3.\2.\1/g" < input

これはすべての項目を(ここでは1つ以上の10進数で構成される任意のシーケンス)<d1>.<d2>.<d3>.<d4>.in-addr.arpaに置き換え、他のすべての項目は変更されません。<d4>.<d3>.<d2>.<d1><dX>

答え2

$ awk '{split($1,p,"."); $1=p[4]"."p[3]"."p[2]"."p[1]} 1' file
1.2.3.10 name hostname

答え3

別のPerlアプローチ:

$ perl -lane '@ip=split(/\./,$F[0]); $F[0]=join(".",reverse(@ip[0..3])); print "@F"' file
1.2.3.10 name hostname

ここでは、.行の最初の4つの区切り要素がIPアドレスであると仮定します。

説明する

  • -lane:このコマンドは、-a入力の各行をスペースに分割し、結果を配列に保存するように機能します。各呼び出しに改行を追加し、入力行から末尾の改行を削除します。これは、「入力を1行ずつ読み、与えられたスクリプトを各行に適用する」ことを意味します。perlawk@F-lprint-n-e
  • @ip=split(/\./,$F[0]):最初のフィールド($F[0])を取得して分割し、.出力を配列に保存します@ip
  • $F[0]=join(".",reverse(@ip[0..3]));:ここにはいくつかの部分があります。まずjoin(CHAR, ARRAY)、ARRAYの要素はCHAR文字を使用して文字列に連結されます。ここでは、配列の最初の4つの要素(インデックス0〜3)を渡すため、例では、@ip数字以外の要素まですべての要素が連結されるため、IPが生成されます。次に、reverse裏返してみてください。最後に結果を$F[0]
  • print "@F":前の手順を完了したら、@F配列に必要なものが含まれているので、それを印刷します。

必要なのは、入力ファイルのすべての行に最初に表示される文字列を削除してから.in-addr.arpaIPを置き換えることである場合は、次のようにできます。

$ perl -pe 's/\.in-addr\.arpa//; s/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/$4.$3.$2.$1/' file
1.2.3.10 name hostname

答え4

別の方法は、正規表現に逆追跡を設定し、逆追跡が最初に達したときに停止する正規表現に組み込まれているループ/スキャン文字列を利用することです。

$ perl -lne '
    m/(.*) ((?<!\d)\d+\.) (?{printf q(%s), $1?$2:$2=~s|\.||r}) (?(?{$1 ne ""}) (?!))/x;
    print /(\s\S.*)/;
' file
1.2.3.10 name hostname

関連情報