Bash 如何让awk不使用空间作为测力计?

Bash 如何让awk不使用空间作为测力计?,bash,csv,awk,space,Bash,Csv,Awk,Space,我正试图处理一个CSV,但我的一些字段包含逗号、换行符和空格,现在我想起来了,里面可能也有一些撇号 对于逗号和换行符,我已经在输出阶段将它们转换为其他字符串,并在最后将它们转换回来(是的,这很混乱,但我只需要运行一次)。我意识到我可能也必须对空格执行此操作,但我已经将问题分解为基本部分,看看是否可以解决它 这是一个input.csv "john","beatles.com","arse","fool@wonka.com","1","1","on holiday" "paul","beatles.

我正试图处理一个CSV,但我的一些字段包含逗号、换行符和空格,现在我想起来了,里面可能也有一些撇号

对于逗号和换行符,我已经在输出阶段将它们转换为其他字符串,并在最后将它们转换回来(是的,这很混乱,但我只需要运行一次)。我意识到我可能也必须对空格执行此操作,但我已经将问题分解为基本部分,看看是否可以解决它

这是一个input.csv

"john","beatles.com","arse","fool@wonka.com","1","1","on holiday"
"paul","beatles.com","bung","","0","1","also on holiday"
(我试过引用和不引用)

这是剧本

INPUT="input.csv"

for i in `cat ${INPUT}`

do
#USERNAME=`echo $i | awk -v  FS=',' '{print $1}'`
USERNAME=`echo $i | awk 'BEGIN{FS="[|,:]"} ; {print $1}'`
echo "username: $USERNAME"

done
所以这应该只是输入john和paul,但我得到

username: "john"
username: holiday"
username: "paul"
username: on
username: holiday"
因为它会看到空格并将其解释为新行


我可以让它停止吗?

您可以在awk中使用任何正则表达式字段分隔符,例如使用可选逗号后跟双引号:

awk -F ',?"' '{print $2, $4, $6, $8, $10, $12, "<" $14 ">"}' f1
john beatles.com arse fool@wonka.com 1 1 <on holiday>
paul beatles.com bung  0 1 <also on holiday>
awk-F',?“{print$2,$4,$6,$8,$10,$12,”}f1
约翰·披头士fool@wonka.com 1 1 
保罗·披头士网站bung 0 1

将最后一个字段
$14
n
<和>
括起来,展示它是如何进入单个awk变量的。

您可以在awk中使用任何正则表达式字段分隔符,例如使用可选的逗号和双引号:

awk -F ',?"' '{print $2, $4, $6, $8, $10, $12, "<" $14 ">"}' f1
john beatles.com arse fool@wonka.com 1 1 <on holiday>
paul beatles.com bung  0 1 <also on holiday>
awk-F',?“{print$2,$4,$6,$8,$10,$12,”}f1
约翰·披头士fool@wonka.com 1 1 
保罗·披头士网站bung 0 1

将最后一个字段
$14
n
<和>
括起来,展示它是如何进入单个awk变量的。

需要注意的几点是,对于
循环,不需要使用
cat
。除非我错过了大局

在文件上调用awk时会发生什么

awk -F"," '{print $1}' input.csv
我得到以下信息:

$ awk -F"," '{print $1}' input.csv
"john"
"paul"
$

有几点需要注意,您不需要使用
cat
for
循环。除非我错过了大局

在文件上调用awk时会发生什么

awk -F"," '{print $1}' input.csv
我得到以下信息:

$ awk -F"," '{print $1}' input.csv
"john"
"paul"
$
无awk的解决方案:

cut -d, -f1 input.csv | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done
以上假设您希望保留引号。如果不是

cut -d, -f1 input.csv | sed 's,^",,;s,"$,,' | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done
以上两种方法都假定字段内容中没有逗号。如果不是这样,请使用您最喜欢的脚本语言中的“适当”CSV解析器。例如

ruby -rcsv -ne 'puts CSV.parse_line($_)[0]' input.csv | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done
无awk的解决方案:

cut -d, -f1 input.csv | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done
以上假设您希望保留引号。如果不是

cut -d, -f1 input.csv | sed 's,^",,;s,"$,,' | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done
以上两种方法都假定字段内容中没有逗号。如果不是这样,请使用您最喜欢的脚本语言中的“适当”CSV解析器。例如

ruby -rcsv -ne 'puts CSV.parse_line($_)[0]' input.csv | while read -r USERNAME ; do echo "username: ${USERNAME}" ; done

导致分词的不是
awk
,而是shell(IFS
的默认值)

你可以说:

while read -r i; do
  USERNAME=$(echo "$i" | awk 'BEGIN{FS="[|,:]"} ; {print $1}');
  echo "username: $USERNAME";
done < $INPUT

在循环中。

导致分词的不是
awk
,而是shell(IFS
的默认值)

你可以说:

while read -r i; do
  USERNAME=$(echo "$i" | awk 'BEGIN{FS="[|,:]"} ; {print $1}');
  echo "username: $USERNAME";
done < $INPUT

在循环中。

也许只是编写一个四行Python脚本?内置的
csv
模块可以解析这一点,没有问题。您的
中有一个问题,因为我在$(cat…
i
将依次获取值
“john”、“beatles.com”、“arse”fool@wonka.com“,”1“,”1“,”on
,”假日“,”保罗“,”披头士“,”0“,”1“,“也,
上,
假日”
。这不是
awk
问题。千万不要,千万不要使用
作为$(cat…)中的i
。谁给你看的?找到他,让他知道不仅他做错了,而且他还在传播坏习惯并浪费你的时间。你真的应该生他的气。现在,为了确保你做对了:不要用
awk
sed
bash
等解析csv文件。使用合适的csv解析器。其他有很多方法在Python、Perl等方面都很好(这只是一个建议,这样你就不会把时间浪费在从一开始就被破坏的方法上)然后只使用shell来调用工具,就像它的意图一样。也许只需要编写一个四行Python脚本?内置的
csv
模块可以解析这一点没有问题。你的
中有一个问题,因为i in$(cat…
i
将依次获取值
“john”、“beatles.com”、“arse”fool@wonka.com“,”1“,”1“,”on
holiday“
“paul”,“beatles.com”,“bung”,“0”,“1”,“还
on
holiday”
。这不是
awk
问题。千万不要,千万不要对$(cat…)中的i使用
。谁给你看的?找到他,让他知道不仅他做错了,而且他还在传播坏习惯并浪费你的时间。你真的应该生他的气。现在,为了确保你做对了:不要用
awk
sed
bash
等解析csv文件。使用合适的csv解析器。其他有很多方法在Python、Perl等方面都很好(这只是一个建议,这样你就不会浪费时间在从一开始就被破坏的方法上)。获得Arnold Robbins(quick!)的《有效的Awk编程,第三版》一书,然后只使用shell调用工具,就像它想要的那样。