按数字排序

按数字排序

我需要按 ISBN 编号(第三列)对列表从输入文件到 a 进行排序file.sh,然后发送到输出文件 ( file.out)。输入文件 ( file.input) 将有一个列表

Donald Smith,Fire Lands,97868545414459
Adam Barry,The Armies,97564325678855
Jennifer Lelan,Childhood dreams,97546766544237

使用循环结构来处理数据和标题Author Name of book ISBN

结果

Author                   Name of Book               ISBN

Jennifer  Lelan    Chilhood Dreams   97546766544237
Adam Barry          The Armies             97564325678855
Donald Smith        Fire Lands              97868545414459

答案1

第一部分是 2023 年添加的新答案。旧答案在分隔符之后仍然可用。

$ mlr --icsv --implicit-csv-header --opprint  label Author,Title,ISBN then sort -n ISBN file.input
Author         Title            ISBN
Jennifer Lelan Childhood dreams 97546766544237
Adam Barry     The Armies       97564325678855
Donald Smith   Fire Lands       97868545414459

这使用磨坊主( mlr) 将数据读取为无标题 CSV,向三个字段添加标签,在字段上对记录进行数字排序ISBN,并以“打印精美”的表格格式输出所有数据。由于 Miller 支持 CSV,因此这可以处理包含嵌入逗号和换行符等的引用字段。

使用'Name of Book'(引用)代替Title较长的标题,如问题中所示。使用--otsv而不是--opprint生成制表符分隔值输出。

重定向命令以>file.output覆盖或创建文件file.output


首先,你会不是循环此数据:为什么使用 shell 循环处理文本被认为是不好的做法?

如果文件中唯一的逗号是分隔字段的逗号,则

sort -t ',' -k3n -o file.output file.input

将根据第三列中的数字对数据进行数字排序。输出将被写入file.output

对于给定的数据,file.output看起来像

Jennifer Lelan,Childhood dreams,97546766544237
Adam Barry,The Armies,97564325678855
Donald Smith,Fire Lands,97868545414459

为了进一步处理这些数据,可以考虑使用一个awk程序。由于您尚未指定要执行哪种处理,因此以下内容只是将每行的数据提取到变量中(并非真正必要)并打印它们:

sort -t ',' -k3n file.input |
awk -F ',' '{ author=$1; title=$2; isbn=$3;
              printf("Author: %s\nTitle: %s\nISBN: %s\n",
                     author, title, isbn) }'

请注意,在这种情况下不需要将排序后的数据存储在中间文件中。

给出问题中数据的输出:

Author: Jennifer Lelan
Title: Childhood dreams
ISBN: 97546766544237
Author: Adam Barry
Title: The Armies
ISBN: 97564325678855
Author: Donald Smith
Title: Fire Lands
ISBN: 97868545414459

为了将数据放入漂亮的列中,并在 ISBN 编号中使用破折号,您不需要awk.以下用于sedISBN 编号的格式设置和column列的格式设置:

sort -t ',' -k3n file.input |
sed -E -e 's/,([0-9]{3})([0-9]{4})([0-9]{5})/,\1-\2-\3-/' |
column -s ',' -t

输出将是

Jennifer Lelan  Childhood dreams  975-4676-65442-37
Adam Barry      The Armies        975-6432-56788-55
Donald Smith    Fire Lands        978-6854-54144-59

请注意,ISBN 数字看起来有点奇怪。那是因为它们的长度是 14 位。 真实的国际标准书号长度为 10 或 13 位,上面的代码假设它们是 13 位数字(或至少 12 位数字)。

要添加列标题:

sort -t ',' -k3n file.input |
{ echo 'Author,Name of book,ISBN'
  sed -E -e 's/,([0-9]{3})([0-9]{4})([0-9]{5})/,\1-\2-\3-/'
} |
column -s ',' -t

哪个产生

Author          Name of book      ISBN
Jennifer Lelan  Childhood dreams  975-4676-65442-37
Adam Barry      The Armies        975-6432-56788-55
Donald Smith    Fire Lands        978-6854-54144-59

...在 shell 中不使用显式循环。

答案2

sort显然是最好的排序工具。

如果awk需要,您可以使用 GNU awk:

gawk -F, '
    {line[$NF] = $0} 
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (isbn in line) print line[isbn]
    }
' file

https://www.gnu.org/software/gawk/manual/html_node/Controlling-Array-Traversal.htmlhttps://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

相关内容