我必须对列中不同数字的文件进行子集化,并在输出中创建多个文件。我试图在循环中执行此操作,但迭代器无法正常工作。
输入(制表符分隔字段)
abc 1
aaa 1
ccc 1
asd 2
sad 2
aaf 3
输出
文件1:
abc 1
aaa 1
ccc 1
文件2:
asd 2
sad 2
文件3:
aaf 3
我的测试是这样的,但它只输出空文件:
for i in $(seq 1 3); do awk -F "\t" '{$2 == $i}' input > cluster.$i.txt; done
答案1
您的代码失败的原因是您尝试在脚本$i
内使用 shell 变量awk
,但这样做不正确。单引号内的文本'...'
由 shell 按字面意思处理,因此$i
被视为两个字符而不是 shell 变量的值$i
。您还尝试将比较作为操作来执行(这意味着没有隐含的操作来打印该行)。
您可以将值传递给awk
awk -F $'\t' -v i="$i" '$2 == i' input > "cluster.$i.txt"
或者您可以根据每一行自身的优点来对待并awk
完全避免:
while read field index
do
printf "%s\t%s\n" "$field" "$index" >> "cluster.$index.txt"
done < input
或者你可以用做awk
同样的事情:
awk '{ fname = "cluster." $2 ".txt"; print > fname }' input
答案2
$i
awk 表达式内部不引用 shell 变量i
。您可以使用命令行传递变量-v i="$i"
并将其引用为 plain i
。
还{....}
定义了一个行动不是一个图案;print
当模式$2 == i
为 true时,您似乎想要执行默认操作 ( )。所以
for i in $(seq 1 3); do
awk -F "\t" -v i="$i" '$2 == i'
input > cluster.$i.txt; done
但是,您可能会考虑执行以下操作,而不是为每个索引调用一次 awk
awk -F "\t" '{print > "cluster" $2 ".txt"}' input
它直接使用输入$2
来构造输出文件名。
请注意,除非您专门尝试防止在空格字符上进行字段分割,否则您可以删除-F "\t"
并允许 awk 在默认的空白分隔符上进行分割。