在bash中按列名剪切列
我想按名称指定一列,即102,找到该列的位置,然后使用类似于cut-5,7的东西,在找到的位置删除指定的列 这是我的文件头delim=\t: 此awk应在以下情况下工作:在bash中按列名剪切列,bash,Bash,我想按名称指定一列,即102,找到该列的位置,然后使用类似于cut-5,7的东西,在找到的位置删除指定的列 这是我的文件头delim=\t: 此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 在bash中使用for循环: C=1; for i in $(head file -n 1) ; do if [ $i ==
awk -F'\t' -v c="102" 'NR==1{for (i=1; i<=NF; i++) if ($i==c){p=i; break}; next} {print $p}' file
在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
在不循环列的情况下尝试解决方案,我得到:
#!/bin/bash
pick="$1"
titles="pos 1 100 102 105"
tmp=" $titles "
tmp="${tmp%% $pick* }"
tmp=($tmp)
echo "column ${#tmp[@]}"
如果找不到列名,它会错误地报告最后一列。这里有一个可能的解决方案,没有只删除一列的限制。它作为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
这几乎肯定需要某种解释。函数的前两行只是从参数中删除文件名,并将其存储起来供以后使用。然后,“剪切”命令将选择适当的列;使用复杂的管道计算列数,如下所示:
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.
尝试此小awk实用程序来切割特定的标题- 示例用法-
awk-f toyeca-cutter.awk-v c=col1,col2,col3,col4 my_file.csvOP想要删除列而不是打印它。如果看不到预期的输出,很难理解需求。cut-d'-f1命令通常只打印单列。这一行代码对我很有帮助,它只想按名称提取字段。也许是其他人要求解决这个不同的问题。我认为$I==102应该是$I=102给我一个这样的错误:正确,这是POSIX。使用BASH,你可以简单地做C++而不是C= $$C+1,甚至。回音$C++作为一个单独的操作。有一个简单的方法来做这一个以上的列吗?用BASH 4。x,是的,有这样一个简单的方式-你可以创建一个关联的列名数组到位置。为什么不要求剪切来补充你的选择当你想删除列,而不是保留它们?至少在Gnu切割的情况下。我认为BSD cut没有这个选择。但移除v非常容易:-
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.