
数値構成スキームにさまざまな数の先行ゼロを追加するために、sed構文を単純化するのに問題があります。私が操作する文字列は次のとおりです。
1.1.1.1,Some Text Here
sed 構文の使用
sed -r ":r;s/\b[0-9]{1,$((1))}\b/0&/g;tr"
私は反応を引き出すことができます
01.01.01.01,Some Text Here
しかし、私が探しているのは、フィールド2と3を最大2桁で埋め、フィールド4を最大3桁で埋め、すべての項目の標準長が[0-9]になるようにすることです。 [0-9]{ 2}.[0-9]{2}.[0-9]{3}
1.01.01.001,Some Text Here
私は、生涯の間にピリオドの後の数字だけをキャプチャするために必要なパラメータを含めるように境界を変更する方法さえ知りません。私はこれが\ bを使用することに関連していると思います。単語の境界ではゼロ文字と一致することを理解していますが、一致にピリオドを追加しようとすると失敗する理由はわかりません。次のように:
sed -r ":r;s/\.\b[0-9]{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b\.[0-9]{1,$((1))}\b/0&/g;tr"
Both cause the statement to hang
sed -r ":r;s/\b[0-9]\.{1,$((1))}\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\.\b/0&/g;tr"
sed -r ":r;s/\b[0-9]{1,$((1))}\b\./0&/g;tr"
cause the statement to output:
1.01.01.1,Some Text Here
また、ステートメントに次のテキストが含まれている場合、追加の問題が発生すると予想されます。
1.1.1.1,Some Number 1 Here
sedとそのすべての複雑さを本当に学ばなければならないというのは既定事実でした。私はこの問題を解決しようとしていますが、この特定の声明はしばらくの間問題を引き起こすと予想しています。どんな助けでも大変感謝します。
編集:方法が見つかりました...このステートメントは私が望むように動作するようですが、これを行うためのよりエレガントな方法が必要です。
sed -r ':r;s/\b[0-9]{1,1}\.\b/0&/;tr;:i;s/\b[0-9]{1,2},\b/0&/;ti;s/.//'
また、構文的に言えば、同様の数値書式がテキストに表示されると問題が発生する可能性があります。
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3
この場合、次のような結果が発生します。
1.01.01.001,Some Text Referring to Document XXX Heading 01.02.03
解決済み 助けてくれてありがとう。最初は、以下の許可された回答を使用して問題を解決しました。次のソートを活用するより大きなソリューションの一部として、このソリューションをPythonに移動したいと思います。
def getPaddedKey(line):
keyparts = line[0].split(".")
keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
return '.'.join(keyparts)
s=sorted(reader, key=getPaddedKey)
答え1
bashはこれを処理できます。しかし、Perlよりはるかに遅いです。
echo "1.1.1.1,Some Text Here" |
while IFS=., read -r a b c d text; do
printf "%d.%02d.%02d.%03d,%s\n" "$a" "$b" "$c" "$d" "$text"
done
1.01.01.001,Some Text Here
答え2
perl
具体的には解決策を要求しませんでしたが、とにかくここに1つあります。私は個人的にこれが読みやすくなると思います。特に、複数行に分けた場合、さらにそうです。
最初の行:
(
echo '1.2.3.4,Some Text Here'
echo '1.01.01.1,Some Text Here'
echo '1.1.1.1,Some Number 1 Here'
echo '1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3'
echo '1.2.3.4,Some \n \s \text'
) |
perl -ne '($ip, $text) = split(/,/, $_, 2); $ip = sprintf("%1d.%02d.%03d.%03d", split(/\./, $ip)); print "$ip,$text"'
その結果:
1.02.003.004,Some Text Here
1.01.001.001,Some Text Here
1.01.001.001,Some Number 1 Here
1.01.001.001,Some Text Referring to Document XXX Heading 1.2.3
1.02.003.004,Some \n \s \text
以下は分析されコメント化されたスクリプトです(フラグはperl
コードの周りに-n
暗黙のループを配置します)。while read; do ... done
($ip, $text) = split(/,/, $_, 2); # Split line into two parts by comma
@octets = split(/\./, $ip) # Split IP address into octets by dots
$ip = sprintf("%1d.%02d.%03d.%03d", @octets); # Apply the formatting
print "$ip,$text" # Output the two parts
答え3
使用法: leading_zero.sh input.txt
#!/bin/bash
sed -r '
s/\.([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,3},)/.0\1.0\2.00\3/
s/\.0*([0-9]{2})\.0*([0-9]{2})\.0*([0-9]{3})/.\1.\2.\3/
' "$1"
説明する:
- 最初の置換は、各数値に特定の数のゼロを追加します。 1つの0〜2桁および3桁、2つの0〜4桁。すでに数桁あるかどうかは問題ではありません。
- 2番目の置換は追加のゼロをすべて削除し、必要な桁数だけを残します。 2、3つの数字には2桁の数字のみを含める必要があります。そのままにして残りは取り除いてください。 4番目の数字には3桁の数字しか含めることができません。そのままにして残りは取り除いてください。
入力.txt
1.1.1.1,Some Text Here
1.1.1.1,Some Text Here
1.11.1.11,Some Text Referring to Document XXX Heading 1.2.3
1.1.1.1,Some Text Here
1.1.11.111,Some Text Referring to Document XXX Heading 1.2.3
1.11.1.1,Some Text Here
出力.txt
1.01.01.001,Some Text Here
1.01.01.001,Some Text Here
1.11.01.011,Some Text Referring to Document XXX Heading 1.2.3
1.01.01.001,Some Text Here
1.01.11.111,Some Text Referring to Document XXX Heading 1.2.3
1.11.01.001,Some Text Here
答え4
perl -pe '/^\d/g && s/\G(?:(\.\K\d+(?=\.))|\.\K\d+(?=,))/sprintf "%0".($1?2:3)."d",$&/ge'
説明する:
ここで使用されるアプローチは、数字の近くを見てそれに応じて行動することです。したがって、2番目と3番目の数字は両側に点があり、4番目の数字は左側に点があり、右側にコンマがあります。
正規表現で2番目または3番目の数字を含むパスを使用すると、$ 1が設定されるため、精度は2で埋められます。 OTOH、4番目の数字のパディングは3です。
%猫ファイル.txt
1.00.3.4,Some Text Here
1.01.01.1,Some Text Here
1.0.01.1,Some Number 1 Here
1.1.1.1,Some Text Referring to Document XXX Heading 1.2.3.4
1.2.3.4,Some \n \s \text
結果:
1.00.03.004,Some Text Here
1.01.01.001,Some Text Here
1.00.01.001,Some Number 1 Here
1.01.01.001,Some Text Referring to Document XXX Heading 1.2.3.4
1.02.03.004,Some \n \s \text