输入(制表符分隔字段)

输入(制表符分隔字段)

我必须对列中不同数字的文件进行子集化,并在输出中创建多个文件。我试图在循环中执行此操作,但迭代器无法正常工作。

输入(制表符分隔字段)

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

$iawk 表达式内部不引用 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 在默认的空白分隔符上进行分割。

相关内容