行と列の多い大容量ファイルがあります。内容の値は-2と2の間です。絶対値より小さい値をゼロに変更したいと思います。たとえば、-0.3または0.6(絶対値0.3と0.6)がある場合は、これを0に変更したいと思います。誰もがこれを行う良い方法を知っていますか?
答え1
perl -pe 's/\S+/abs($&) < 1 ? 0 : $&/ge' < your-file
ここで、等数はperl
許可されますが、16進数またはその他の記号は許可されません(0x12は0として扱われ、010は8ではなく10として扱われます)。0.123
-12e-4
例:
$ echo "1.2 120e-4 0.001e4 -0.2" | perl -pe 's/\S+/abs($&) < 1 ? 0 : $&/ge'
1.2 0 0.001e4 0
答え2
awk '{
for (i=1; i<= NF; i++) {
if($i < 1 && $i > -1) { $i=0; }
}
print }' file
...awkを使用してインポートします。
sedを使用する(2つの式をこの順序で維持しないように注意してください。そうしないと負のゼロになります):
sed -e 's/-0\.[0-9]*/0/g' -e 's/0\.[0-9]*/0/g' file
楽しみのためにbashにソリューションを追加する:
#!/usr/bin/env bash
# for extended pattern matching, to grab repeated [:digits:]
shopt -s extglob
# to prevent filename globbing
set -f
while read line
do
# specifically left $line unquoted to allow splitting
for f in $line
do
f=${f/-0.*([[:digit:]])/0}
f=${f/0.*([[:digit:]])/0}
printf "%s " $f
done
printf "\n"
done
これにより、各行に末尾のスペースが追加されます。これをパイプして末尾のsed 's/ $//'
スペースを削除します。
...もっと楽しくするために(bash-ismsを使わずに)シェル/grepソリューションを追加します。
set -f
while read line
do
# specifically left $line unquoted to allow splitting
for f in $line
do
echo $f | grep -q -E -- '-?0\.[[:digit:]]'
if [ $? -eq 0 ]
then
printf "0 "
else
printf "%s " $f
fi
done
printf "\n"
done
この-q
フラグはgrepの出力を沈黙させます。私たちが望むのは戻りコードだけです。この-E
フラグは「[0-9]」の代わりに「[:digit:]」を有効にします。また、各行に末尾のスペースを追加して、末尾のsed 's/ $//'
スペースを削除します。
答え3
アッ
awk '{ for(i=1;i<=NF;i++)if(sqrt($i^2)<1){printf "0 "}else{printf "%s ", $i}print ""}'
必要に応じて動作する必要があります。 (しかし、移植性がなく、sqrt()への不要な呼び出しが含まれています。Jeff Schallersの答えが良いです。)
-loopはfor
テーブル列を繰り返し、sqrt($i^2) <1
条件(sqrt(x*x)
またはsqrt(x^2)
結果はxの絶対値)でした。0
絶対値が小さい場合はif-else部分が印刷され0.6
、値が大きいと印刷されます$i
。
これがあなたが望むものであることを願っています。
ノート
別のフィールド区切り文字が必要な場合は、追加' '
オプションを追加する必要があります。
AWKのマニュアルページ - http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_23.html