我需要按 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
.以下用于sed
ISBN 编号的格式设置和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.html和https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html