我有以下数据集:
M1 1 1233
M2 1 3212
M3 1 55323
M4 1 4444233
M5 1 23444
M6 1 555333
M7 1 55567
M8 2 22224
M9 2 55566
M10 2 4567
M11 3 44242
M12 3 234234
M13 4 2233
M14 4 2442
M15 4 322352
M16 4 235242
M17 4 2324524
M18 5 232342
M19 6 2322523
M20 6 2332523
我想根据第二列的值创建一个数组。我想在1
第二列中的所有行中应用其他命令,在2
第二列中的行中应用其他命令,依此类推,并将它们保存在不同的文件中,但我不知道如何执行此操作。我尝试使用 while
命令,但所有尝试都失败了。
该代码的输出应该是数组每个索引中原始文件的子集;例如:
索引 i1
M1 1 1233
M2 1 3212
M3 1 55323
M4 1 4444233
M5 1 23444
M6 1 555333
M7 1 55567
索引 i2
M8 2 22224
M9 2 55566
M10 2 4567
依此类推,直到
索引 i6
M19 6 2322523
M20 6 2332523
在这些索引中,我想应用其他命令。
我如何在 shell 脚本和/或 awk 中执行此操作?
答案1
您可以从 awk 获得最佳结果:
awk '{ print > "index i"$2 }' < input
您也可以纯粹在 shell 中执行此操作:
while read a b c
do
printf '%s\n' "$a $b $c" >> "index i$b"
done < input
awk 解决方案具有以下优点:
- 它将覆盖现有文件。 shell 脚本将附加到现有文件中。 (我想这可能就是您想要的。在这种情况下,您可以通过使用
>>
而不是>
在 awk 脚本中来实现。) - awk 脚本保留输入文件的间距。 shell 脚本将多个空格缩减为单个空格。
- 对于大数据文件,awk 脚本可能会稍微快一些。
答案2
添加到 G-Man 的答案:是的,您可以仅使用 sh 获得完全相同的结果(因为这是您重复问题中的规范那里,这是我在 G-Man 回答之前 9 小时回答的)。
有一个内置函数set
允许您为$1
$2
等等赋值$3
。以下是 bash 手册页的引用(这也适用于 sh):
设置[{-选项| +选项 | -- }] arg ...
set 命令的第三个用途是将 shell 的位置参数的值设置为指定的 args。要更改位置参数而不更改任何选项,请使用“--”作为要设置的第一个参数。如果不存在args,set命令将清除所有位置参数(相当于执行“shift $#”。)
所以我们可以这样做:
set -f
while read ln; do
set -- $ln
printf '%s\n' "$ln" >> "index i"$2
done < input
set +f
在 中set -- $ln
,$ln
被分成多个字段,第 n 个字段被分配给第 n 个位置参数。
下一行的引用$ln
确保内容的完整性(保留间距等)。
和set -f
是set +f
为了防止像 * 和 ? 这样的通配字符?在文件中免于混乱set
。感谢斯科特提出这个问题。
相反printf
,我最初使用的是echo
.但多亏了斯科特的第二条评论(如果对手将一行更改为、echo
等选项,那么就会感到困惑),而是用来防止这种情况。-n
-e
echo
printf
这表明 sh 可能不是此类工作的理想选择。至少使用支持正则表达式的 bash。但是,如果你尝试的话,这是可行的。
至于 awk,嗯,它不是“稍微快一点”,而是在不考虑磁盘 IO 的情况下快一个数量级。所以优先使用awk。
顺便说一句,我相信你没有听说过这样一句话:“如果两个答案是一个太多,那么两个问题就是两个太多”。
因为我刚刚说过了;)
但下次做出选择并坚持下去,这样我们就能集中精力。
答案3
命令
for i in `awk '{if(!seen[$2]++)print $2}' y.txt`;do awk -v i="$i" 'BEGIN {print "index i"i}$2==i {print $0}END {print "========================================"}' y.txt; done
输出
index i1
M1 1 1233
M2 1 3212
M3 1 55323
M4 1 4444233
M5 1 23444
M6 1 555333
M7 1 55567
========================================
index i2
M8 2 22224
M9 2 55566
M10 2 4567
========================================
index i3
M11 3 44242
M12 3 234234
========================================
index i4
M13 4 2233
M14 4 2442
M15 4 322352
M16 4 235242
M17 4 2324524
========================================
index i5
M18 5 232342
========================================
index i6
M19 6 2322523
M20 6 2332523
========================================