我正在尝试仅打印 CSV 文件中的匹配模式。示例:所有以 开头的列值35=its value
。谢谢。
CSV 文件:
35=A,D=35,C=129,ff=136
D=35,35=BCD,C=129,ff=136
900035=G,D=35,C=129,ff=136
35=EF,D=35,C=129,ff=136,35=G
36=o,D=35,k=1
输出:
35=A
35=BCD
35=EF
35=G
我使用的命令不起作用:
sed -n '/35=[A-Z]*?/ s/.*\(35=[A-Z]*?\).*/\1/p' filename
答案1
用于用tr
换行符替换所有逗号,然后grep
获取以字符串开头的所有行35=
:
$ tr ',' '\n' <data.in | grep '^35='
35=A
35=BCD
35=EF
35=G
答案2
使用GNU grep
它支持-o
仅打印匹配字符串的选项,每个字符串都在自己的行上
$ grep -oE '\b35=[^,]+' ip.csv
35=A
35=BCD
35=EF
35=G
\b
是单词边界,所以900035
不会匹配[^,]+
匹配一个或多个非,
字符- 假设值不包含
,
和awk
$ awk -F, '{ for(i=1;i<=NF;i++){if($i~/^35=/) print $i} }' ip.csv
35=A
35=BCD
35=EF
35=G
-F,
设置,
为输入字段分隔符for(i=1;i<=NF;i++)
迭代所有字段if($i~/^35=/)
如果字段开头为35=
print $i
打印该字段
与......类似perl
perl -F, -lane 'foreach (@F){print if /^35=/}' ip.csv
答案3
使用 Perl:
$ perl -lne 'print for /(\b35=[^,]+)/g' filename
35=A
35=BCD
35=EF
35=G
或者也许更普遍/稳健地使用文本::CSV 模块
$ perl -MText::CSV -lne '
BEGIN{$p = Text::CSV->new()}
print for grep { /^35=/ } $p->fields(), $p->parse($_)
' filename
35=A
35=BCD
35=EF
35=G
答案4
纯 Bash 解决方案:
( # Use parentheses as scope for IFS
IFS=$',\n' # Split on both , or \n
for c in $(</tmp/file.csv) # For every column or row
do
[[ "$c" =~ ^35= ]] && echo ${line##35=} # Find ^35= and print while removing ^35=
done
) # Optionally >/tmp/filtered-output.txt
笔记,仅出于其可读性和灵活性而使用它 - 如果您可以阅读它,否则可以使用以下方法:
# Read | Replace | Find | Remove
cat /tmp/file.csv | tr ',' '\n' | grep '^35=' | sed 's/^35=//'
这更加直观和高效。
输入(/tmp/file.csv):
35=A,D=35,C=129,ff=136
D=35,35=BCD,C=129,ff=136
900035=G,D=35,C=129,ff=136
35=EF,D=35,C=129,ff=136,35=G
36=o,D=35,k=1
输出:
A
BCD
EF
G