unix 如果分隔符字符在双引号内,则剪切输出不正确

r6vfmomb  于 8个月前  发布在  Unix
关注(0)|答案(3)|浏览(66)

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)
epfja78i

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
jaxagkaj

jaxagkaj2#

或者使用python

#! /usr/bin/env python3

import csv
import sys

for row in csv.reader(sys.stdin):
    print(row[1])
ncecgwcz

ncecgwcz3#

您可以使用一些regex和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
  1. sed -r 's/("\s*,|,\s*"|"\s*,\s*")/\\,/g':基于正则表达式,将所有“外部”逗号和双引号替换为\,。示例案例:",,"","。(您可以选择其他类型,而不是\,
  2. tr -d '"':删除开头和结尾的双引号。
  3. awk '{split($0, array, "\\\\,"); print array[2]}':通过awk拆分内存。(ref:How to split a delimited string into an array in awk?
# 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.关于将变量放在单引号内,转义模式类似于:

# before
 'foobar'
#|^^^^^^|

# after
 'foo'${my_var}'bar'
#|^^^|         |^^^|

相关问题