如何交换 tsv 文件中的列,同时保留制表符分隔符?

如何交换 tsv 文件中的列,同时保留制表符分隔符?

例如,您有:

姓名 1 2 3 4 5 6 7 8

带制表符分隔符 ^

我想在 2 列之间切换(例如,如果从 0 开始,则为第 7 列和第 8 列),因此它看起来像:

姓名 1 2 3 4 5 6 8 7

最终,它可能应该是其他列索引。

我尝试使用 awk 但出现很多错误。你能解释一下吗?

我尝试的命令是:

awk ' { t = $10; $10 = $9; $9 = t; print > "test2.txt"; } ' test.txt 

它创建了一个新文件,但没有制表符分隔符。 (带空格分隔符)

答案1

我不知道如何 awk 这个,所以这里是简单的 bash 脚本:

#!/usr/bin/env bash

while IFS='' read -r i || [[ -n "$i" ]]; do
  cut -f1,2,3 -z <<<"$i"
  printf '\t'
  cut -f10 -z <<<"$i"
  printf '\t'
  cut -f5,6,7,8,9 -z <<<"$i"
  printf '\t'
  cut -f4 <<<"$i"
done <colinput.txt

“-z”剪切选项不打印换行符。不可能有选项,-f1,2,3,4,5,6,8,7因为剪切不会更改输出中的列位置。 cut 默认分隔符是制表符。

答案2

您只需指定分隔符即可。在 awk 中,输入字段分隔符是 FS 变量,相应地输出字段分隔符是OFS。以下是指定这些变量的一些方法:

  1. 在 BEGIN 块中分配变量:

    awk 'BEGIN {FS = OFS = "\t"} { t = $10; $10 = $9; $9 = t; print } ' test.txt > test2.txt
    
  2. 在 awk 正文之后设置文件列表中的变量

    awk '{ t = $10; $10 = $9; $9 = t; print } ' FS='\t' OFS='\t' test.txt > test2.txt
    
  3. 使用 -F 和 -v 选项

    awk -F '\t' -v OFS='\t' '{ t = $10; $10 = $9; $9 = t; print } ' test.txt > test2.txt
    

此外,要指定列号,您可以使用这些相同的技术。我更喜欢使用 -v 因为这是传递参数的最干净的方式变量转化为awk多变的。

awk -F '\t' -v OFS='\t' -v a=9 -v b=10 '{
    t  = $a
    $a = $b
    $b = t
    print 
}' test.txt > test2.txt

相关内容