[英]Sort the tab-delimited numbers on each line of a file
我正在尝试分别在文件的每一行上对数字进行排序。 一行中的数字由制表符分隔。 (我使用空格,但它们实际上是制表符。)
例如,对于以下输入
5 8 7 6
1 5 6 8
8 9 7 1
所需的输出将是:
5 6 7 8
1 5 6 7
1 7 8 9
到目前为止,我的尝试是:
let i=1
while read line
do
echo "$line" | tr " " "\n" | sort -g
cut -f $i fileName | paste -s >> tempFile$$
((++i))
done < fileName
这是我所能得到的最好的-我相信可以用awk / sed / perl用6个字符完成:
while read line
do
echo $(printf "%d\n" $line | sort -n) | tr ' ' \\t >> another-file.txt
done < my-input-file.txt
使用一些特定于GNU awk的功能:
$ awk 'BEGIN{ PROCINFO["sorted_in"] = "@ind_num_asc" }
{ delete(a); n = 0; for (i=1;i<=NF;++i) a[$i];
for (i in a) printf "%s%s", i, (++n<NF?FS:RS) }' file
5 6 7 8
1 5 6 8
1 7 8 9
每个字段都设置为数组a
的键。 在GNU awk中,可以指定for (i in a)
循环遍历数组的顺序-在这里,我将其设置为以数字顺序递增。
这是一个可以执行此操作的bash脚本。 它采用文件名参数或读取stdin,已在CentOS上进行了测试,并假定IFS = $'\\ t \\ n'。
#!/bin/bash
if [ "$1" ] ; then exec < "$1" ; fi
cat - | while read line
do
set $line
echo $(for var in "$@"; do echo $var; done | sort -n) | tr " " "\t"
done
如果要将输出放在另一个文件中,请按以下方式运行它:
cat input_file | sorting_script> another_file
要么
sorting_script输入文件>另一个文件
考虑为此使用perl
:
perl -ape '@F=sort @F;$_="@F\n"' input.txt
在这里, -a
将自动字段拆分(如awk
一样)打开到数组@F中, -p
使它执行每行脚本并每次打印$_
,- -e
直接在命令行上指定脚本。
恐怕肖恩(Sean)的字符数不超过6个。
这在awk中本来应该很简单,但是并没有所需的功能。 如果存在与$1
, $2
等字段相对应的数组$@
,则解决方案将是awk '{asort $@}' input.txt
,但可惜没有这样的数组退出。 将字段移入数组并再次移出数组所需的循环使其比bash版本更长:
awk '{for(i=1;i<=NF;i++)a[i]=$i;asort(a);for(i=1;i<=NF;i++)printf("%s ",a[i]);printf("\n")}' input.txt
因此, awk
不是此处工作的正确工具。 sort
本身没有开关来控制其排序方向也有点奇怪。
使用awk
$ cat file
5 8 7 6
1 5 6 8
8 9 7 1
$ awk '{c=1;while(c!=""){c=""; for(i=1;i<NF;i++){n=i+1; if($i>$n){c=$i;$i=$n;$n=c}}}}1' file
5 6 7 8
1 5 6 8
1 7 8 9
更好的可读性
awk '{
c=1
while(c!="")
{
c=""
for(i=1;i<NF;i++)
{
n=i+1
if($i>$n)
{
c=$i
$i=$n
$n=c
}
}
}
}1
' file
如果您有ksh
,可以尝试一下
#!/usr/bin/env ksh
while read line ; do
set -s +A cols $line
echo ${cols[*]}
done < "input_file"
测试
[akshay@localhost tmp]$ cat test.ksh
#!/usr/bin/env ksh
cat <<EOF | while read line ; do set -s +A cols $line; echo ${cols[*]};done
5 8 7 6
1 5 6 8
8 9 7 1
EOF
[akshay@localhost tmp]$ ksh test.ksh
5 6 7 8
1 5 6 8
1 7 8 9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.