cut -f2 -d”,”-不能正确获取第二列,因为第一列被封装在双引号内。
"Foo News, Videos (Android)","Foo News, Videos - Android","Foo News, Videos (Android)" Bar News (iOS),"Bar News, Movie - iOS",Bar News & Movie (iOS)
epfja78i1#
在bash 5.2中,可以执行以下操作:这个版本的bash附带了一个“delimiter-separated values”模块,它支持双引号字段。
enable dsv while IFS= read -r line; do dsv -a fields "$line" declare -p fields printf '%s\n' "${fields[1]}" done < file.csv
declare -a fields=([0]="Foo News, Videos (Android)" [1]="Foo News, Videos - Android" [2]="Foo News, Videos (Android)") Foo News, Videos - Android declare -a fields=([0]="Bar News (iOS)" [1]="Bar News, Movie - iOS" [2]="Bar News & Movie (iOS)") Bar News, Movie - iOS
在我的~/.bashrc中有这样的代码来简化:
# for loadable builtins bash_root=${BASH%/bin/bash} [[ -d "$bash_root/lib/bash" ]] && BASH_LOADABLES_PATH="$bash_root/lib/bash" unset bash_root
jaxagkaj2#
或者使用python
#! /usr/bin/env python3 import csv import sys for row in csv.reader(sys.stdin): print(row[1])
ncecgwcz3#
您可以使用一些regex和awk来满足您的需要。假设您的数据存储在test.csv中。
awk
test.csv
cat test.csv | sed -r 's/("\s*,|,\s*"|"\s*,\s*")/\\,/g' | tr -d '"' | awk '{split($0, array, "\\\\,"); print array[2]}' # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # 1 2 3
sed -r 's/("\s*,|,\s*"|"\s*,\s*")/\\,/g'
\,
",
,"
","
tr -d '"'
awk '{split($0, array, "\\\\,"); print array[2]}'
# result Foo News, Videos - Android Bar News, Movie - iOS
为了参数化列,以防万一,你需要调整awk中的单引号来转义变量:
show_column () { column=$1 cat test.csv | sed -r 's/("\s*,|,\s*"|"\s*,\s*")/\\,/g' | tr -d '"' | awk '{split($0, array, "\\\\,"); print array['${column}']}' }
$ show_column 1 Foo News, Videos (Android) Bar News (iOS) $ show_column 2 Foo News, Videos - Android Bar News, Movie - iOS $ show_column 3 Foo News, Videos (Android) Bar News & Movie (iOS)
1.如果你的csv中有一些像foo,bar,bar(没有任何双引号)的情况,你需要删除sed部分,只需要使用awk即可。因为上面的正则表达式是基于双引号的。1.如果列中有纯逗号,例如。"foo", ",", ",", "bar",应该将regex改为。关键策略是替换“外部”逗号。1.关于将变量放在单引号内,转义模式类似于:
foo,bar,bar
sed
"foo", ",", ",", "bar"
# before 'foobar' #|^^^^^^| # after 'foo'${my_var}'bar' #|^^^| |^^^|
3条答案
按热度按时间epfja78i1#
在bash 5.2中,可以执行以下操作:这个版本的bash附带了一个“delimiter-separated values”模块,它支持双引号字段。
在我的~/.bashrc中有这样的代码来简化:
jaxagkaj2#
或者使用python
ncecgwcz3#
您可以使用一些regex和
awk
来满足您的需要。假设您的数据存储在
test.csv
中。sed -r 's/("\s*,|,\s*"|"\s*,\s*")/\\,/g'
:基于正则表达式,将所有“外部”逗号和双引号替换为\,
。示例案例:",
,"
","
。(您可以选择其他类型,而不是\,
。tr -d '"'
:删除开头和结尾的双引号。awk '{split($0, array, "\\\\,"); print array[2]}'
:通过awk
拆分内存。(ref:How to split a delimited string into an array in awk?)为了参数化列,以防万一,你需要调整
awk
中的单引号来转义变量:注意事项
1.如果你的csv中有一些像
foo,bar,bar
(没有任何双引号)的情况,你需要删除sed
部分,只需要使用awk
即可。因为上面的正则表达式是基于双引号的。1.如果列中有纯逗号,例如。
"foo", ",", ",", "bar"
,应该将regex改为。关键策略是替换“外部”逗号。1.关于将变量放在单引号内,转义模式类似于: