我会用它sed来处理示例数据文件,因为它简单快捷。这需要一种将行号文件转换为适当sed脚本的机制。有很多方法可以做到这一点。
一种方法用于sed将一组行号转换为sed脚本。如果一切都是标准输出,这将是微不足道的。由于输出需要转到不同的文件,我们需要行号文件中每一行的行号。给出行号的一种方法是nl命令。另一种可能性是使用pr -n -l1. 相同的sed命令行适用于两者:
nl linenumbers.txt |
sed 's/ *\([0-9]*\)[^0-9]*\([0-9]*\)|\([0-9]*\)/\2,\3w file\1.txt/'
对于给定的数据文件,生成:
345,789w > file1.txt
999,1056w > file2.txt
1522,1366w > file3.txt
3523,3562w > file4.txt
另一种选择是awk生成sed脚本:
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt
如果您的版本sed允许您使用-f -(GNU允许sed;BSDsed不允许)从标准输入读取其脚本,那么您可以将行号文件动态转换为sed脚本,并使用它来解析示例数据:
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f - sample.data
如果您的系统支持/dev/stdin,您可以使用以下之一:
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f /dev/stdin sample.data
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt |
sed -n -f /dev/fd/0 sample.data
如果做不到这一点,请使用显式脚本文件:
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt > sed.script
sed -n -f sed.script sample.data
rm -f sed.script
严格来说,您应该确保临时文件名是唯一的 ( mktemp) 并且即使脚本被中断 ( trap) 也会被删除:
tmp=$(mktemp sed.script.XXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
awk -F'|' '{ printf "%d,%dw > file%d.txt\n", $1, $2, NR }' linenumbers.txt > $tmp
sed -n -f $tmp sample.data
rm -f $tmp
trap 0
finaltrap 0允许你的脚本成功退出;省略它,您的脚本将始终以状态 1 退出。
我忽略了 Perl 和 Python;任何一个都可以在单个命令中用于此目的。文件管理非常繁琐,使用起来sed似乎更简单。您也可以使用 just awk,或者使用第一个awk脚本编写awk脚本来完成繁重的工作(上面的微不足道的扩展),或者让单个awk进程读取两个文件并产生所需的输出(更难,但远非不可能)。
如果不出意外,这表明有许多可能的方法来完成这项工作。如果这是一次性练习,那么您选择哪一种并不重要。如果您将重复执行此操作,请选择您喜欢的机制。如果您担心性能,请测量。将行号转换为命令脚本的成本可能可以忽略不计;使用命令脚本处理样本数据是花费时间的地方。我希望sed在那一点上表现出色;我没有测量以确认它确实如此。