我有一个包含很多行和列的大文件;内容的值在 -2 和 2 之间。我有兴趣替换绝对值形式小于的值;我想用 0 替换它们。例如,如果有 -0.3 或 0.6(绝对值 0.3 和 0.6),我想用零替换它们。有人知道这样做的好方法吗?
答案1
perl -pe 's/\S+/abs($&) < 1 ? 0 : $&/ge' < your-file
此处,perl
将接受0.123
、等数字-12e-4
,而不是十六进制或其他符号(0x12 将被视为 0,010 将被视为 10,而不是 8)。
例子:
$ 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 (注意不要按此顺序保留两个表达式,否则最终会得到负零):
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/ $//'
以删除尾随空格。
...并添加 shell/grep 解决方案(不使用任何 bash-isms),只是为了更多乐趣:
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
标志启用“[:digit:]”而不是“[0-9]”。请注意,这还会为每行添加尾随空格;通过管道将其删除sed 's/ $//'
以删除尾随空格。
答案3
awk
awk '{ for(i=1;i<=NF;i++)if(sqrt($i^2)<1){printf "0 "}else{printf "%s ", $i}print ""}'
这应该做你想做的。 (但它无法移植,并且包含对 sqrt() 的不必要的调用。Jeff Schallers 的答案更好。)
-loopfor
循环遍历您的表列,the sqrt($i^2) <1
was 您的条件(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