我想按名称指定列(即102
),找到此列的位置,然后使用cut -5,7-
之类的内容删除指定的列。
这是我的文件标题(delim = "\t"
):
#CHROM POS 1 100 101 102 103 107 108
答案 0 :(得分:1)
这个awk应该可以工作:
awk -F'\t' -v c="102" 'NR==1{for (i=1; i<=NF; i++) if ($i==c){p=i; break}; next} {print $p}' file
答案 1 :(得分:0)
在bash中使用for
循环:
C=1; for i in $(head file -n 1) ; do if [ $i == "102" ] ; then break ; else C=$(( $C + 1 )) ; fi ; done ; echo $C
一个完整的脚本
C=1
for i in $(head in_file -n 1) ; do
echo $i
if [ $i == "102" ] ; then
break ;
else
echo $C
C=$(( $C + 1 ))
fi
done
cut -f1-$(($C-1)),$(($C+1))- in_file
答案 2 :(得分:0)
尝试解决方案而不循环遍历列,我得到:
#!/bin/bash
pick="$1"
titles="pos 1 100 102 105"
tmp=" $titles "
tmp="${tmp%% $pick* }"
tmp=($tmp)
echo "column ${#tmp[@]}"
如果无法找到列名,则会错误地报告最后一列。
答案 3 :(得分:0)
这是一种可能的解决方案,没有限制只删除一列。它被写为bash函数,其中第一个参数是文件名,其余参数是要排除的列。
rmcol() {
local file=$1
shift
cut -f$(head -n1 "$file" | tr \\t \\n | grep -vFxn "${@/#/-e}" |
cut -d: -f1 | paste -sd,) "$file"
}
如果您要选择而不是排除指定列,请将-vFxn
更改为-Fxn
。
这几乎肯定需要某种解释。函数的前两行只是从参数中删除文件名并存储它以供以后使用。然后cut
命令将选择适当的列;列号用复杂的管道计算如下:
head -n1 "$file" | # Take the first line of the file
tr \\t \\n | # Change all the tabs to newlines [ Note 1]
grep # Select all lines (i.e. column names) which
-v # don't match
F # the literal string
x # which is the complete line
n # and include the line number in the output
"${@/#/-e}" | # Put -e at the beginning of each command line argument,
# converting the arguments into grep pattern arguments (-e)
cut -d: -f1 | # Select only the line number from that matches
paste -sd, # Paste together all the line numbers, separated with commas.
答案 4 :(得分:0)
尝试使用该小型awk实用程序剪切特定的标头-https://github.com/rohitprajapati/toyeca-cutter
示例用法-
awk -f toyeca-cutter.awk -v c =“ col1,col2,col3,col4” my_file.csv