我有一个网格模型数据(按不同深度分隔)保存在文本文件中。结构是这样的:
格式文本文件中一行中的每一列:
x_coordinate y_coordinate density
每个文本文件中大约有400*400个点(作为一定深度的平面)。
文件名:
dep###
这里,###
是一个代表深度(Z 方向)的数字。该数字可以是整数或分数。例如,现在我有这些文件:“dep0”、“dep0.5”、“dep10”、“dep300”,这意味着这些数据是 xy 平面形式的 400*400 网格数据,深度为 0、0.5、10 和300.
现在,我想选取文件名中的数字(又称深度)并将其添加到每行的第三列,将它们全部组合在一起。此外,深度应从最小值到最大值排序。所以输出文件应该如下所示(例如):
x_coordinate y_coordinate z_coordinate density
0 0 0 2.5
0 1 0 2.5
... ... 0 2.6
400 400 0 2.9
0 0 0.5 2.8
... ... 0.5 2.9
0 0 10 3.2
... ... 10 3.3
... ... 300 4.7
... ... 300 4.8
起初我是用这个脚本来做的:
for((i=$depmin;i<=$depmax;i++))
do
if [ -f "xyp/dep"$i ];then
awk '{print $1, $2,'$i',$3}' "xyp/dep"$i >> "xyzp/area1"
fi
done
然后我发现它会错过任何深度不是整数的文件,因为变量$i每轮循环中for
增加1。
我尝试过使用sed
and find -exec
,但我不断收到错误。对我来说,困难在于我不太明白如何正确使用$
, ''
,<<<
将值重定向或通过管道传递到awk
或其他函数。请帮我解决这个问题。
=====================
我想出了这个脚本:
depnumbers=$(ls xyp | sed -e 's/dep//g' |sort -n)
filecount=$(ls xyp | wc -l)
for((i=1;i<=$filecount;i++))
do
dep=$(awk '{print $'$i'}' <<< $depnumbers)
awk '{print $1, $2,'$dep',$3}' "xyp/dep"$dep >> "xyzp/area1"
done
它工作得很好。对于此类任务,有什么方法可以简化或改进此脚本吗?实际上我是 bash 的新手,但仍然认为有些问题......不确定
答案1
仅用于将数字添加到文件中。
awk 'NR>1{print $1,$2,substr(FILENAME,7),$4 }' xyp/dep* > "xyzp/area1"
用于按数字排序。
ls -1v xyp/dep* | xargs awk 'NR>1{print $1,$2,substr(FILENAME,7),$4 }' > "xyzp/area1"
用于从负数排序。
ls xyp/dep* | sort -t 'p' -k 3 -n | xargs awk 'NR>1{print $1,$2,substr(FILENAME,7),$4 }' > "xyzp/area1"
这会将字符视为p
分隔符,并使函数sort -n
只影响后面的数字。