我会用它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
在那一点上表现出色;我没有测量以确认它确实如此。