![如何交换 tsv 文件中的列,同时保留制表符分隔符?](https://linux22.com/image/152999/%E5%A6%82%E4%BD%95%E4%BA%A4%E6%8D%A2%20tsv%20%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E5%88%97%EF%BC%8C%E5%90%8C%E6%97%B6%E4%BF%9D%E7%95%99%E5%88%B6%E8%A1%A8%E7%AC%A6%E5%88%86%E9%9A%94%E7%AC%A6%EF%BC%9F%20.png)
例如,您有:
姓名 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。以下是指定这些变量的一些方法:
在 BEGIN 块中分配变量:
awk 'BEGIN {FS = OFS = "\t"} { t = $10; $10 = $9; $9 = t; print } ' test.txt > test2.txt
在 awk 正文之后设置文件列表中的变量
awk '{ t = $10; $10 = $9; $9 = t; print } ' FS='\t' OFS='\t' test.txt > test2.txt
使用 -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