我有许多 .dat 文件(变量),每个文件中有 2 条信息,一个重量和一个高度,空格分隔如下,其中 First_Last 是名称:
18kg 1.2m
在“First1_Last1.dat”中
12kg 1.6m
在“First2_Last2.dat”等中。
我需要按每个值中的第一个或第二个值对它们进行排序。我想我必须cat
合并所有文件,用 a 去掉单元cut
(对此不太确定),然后使用paste
和 最后sort -k 1,1 temp.txt
在我的临时文件上将文件名添加为第三列,以获得我想要的输出,同时仍然能够跟踪每个值来自哪个文件,因为我需要关联的名称来按照正确的顺序为每个人打开不同的文件。所以我要使用的输出文件看起来像
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
我想知道是否有更好的方法使用内置的东西或我缺少的 .dat 文件类型的属性来执行此操作。或者也许使用awk
?
答案1
您可以使用grep
和sed
提取排序键并仅指定某些列进行排序:
grep -H kg *.dat \
| sed 's/^\([^:]\+\):\([0-9.]\+\)kg \+\([0-9.]\+\)m.*$/\2 \3 \1/' \
| sort -t' ' -k1,2 -g
输出示例:
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
答案2
如果您的文件每个仅包含一个数据(行),那么像这样简单的事情可能会起作用:
for x in *.dat ; do
echo $(< "$x") $x # print contents of file and add the filename
done | sort -nsk2,2 # stable sort by the second column.
我用 GNU sort 进行了快速测试,并没有真正看到单位或小数出现问题,但我不做任何保证。
答案3
也许使用(最新版本的)GNU awk - 假设“.dat 文件”只是指一个以空格分隔的文本文件:
awk -v sort=2 '
{
gsub(/kg|m/,"",$0);
a[$sort]=$0 FS FILENAME;
}
END {
PROCINFO["sorted_in"]="@ind_num_asc";
for (i in a) print a[i];
}' *.dat
其中变量sort
设置要排序的列(1
或2
);或作为单行
awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
测试
$ awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat
和
$ awk -v sort=2 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
18 1.2 First1_Last1.dat
12 1.6 First2_Last2.dat