절대값이 1보다 작은 모든 값을 0으로 변경

절대값이 1보다 작은 모든 값을 0으로 변경

행과 열이 많은 대용량 파일이 있습니다. 내용의 값은 -2와 2 사이입니다. 절대값보다 작은 값을 0으로 바꾸고 싶습니다. 예를 들어 -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 사용(두 표현식을 이 순서로 유지하지 않도록 주의하세요. 그렇지 않으면 음수 0이 됩니다):

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

관련 정보