从文件读取时如何忽略白色 space 和逗号
How to ignore white space and comma when reading from a file
我有一个逗号分隔的文件,我需要从每个文件中提取第三个字段 line.File test.txt 具有以下内容:
6,STRING TO DECIMAL WITHOUT DEFAULT,cast($src_fld as DECIMAL(15,2) $tgt_fld
7,STRING TO INTERGER WITHOUT DEFAULT,cast($src_fld as integer) $tgt_fld
10,DEFAULT NO RULE,'$default' $tgt_fld
cat test.txt | awk -F, '{print }'
如果我写上面的命令,我会得到一个不正确的输出:
> cast($src_fld as DECIMAL(15
> cast($src_fld as integer) $tgt_fld
> '$default' $tgt_fld
谁能告诉我如何实现 it.I 需要写在一个循环中,以便稍后进行进一步的处理。请注意,每个第三个字段可能包含白色 space 和逗号 (,).
如果前两个字段中有逗号,则您的任务无法完成。
1,second,field,with,commas,third,field,with,commas
您无法知道第二个字段在哪里结束,第三个字段从哪里开始。
您真的必须使用实际的 CSV 语法,并使用 CSV 解析器解析文件。
1,"second,field,with,commas","third,field,with,commas"
如果你能确定前两个字段没有逗号,你可以这样做:
sed 's/^[^,]\+,[^,]\+,//' file
awk
救援!
不是通用解决方案,但适用于您的格式
$ awk -F, '{for(i=4;i<=NF;i++) = FS $i} {print }' badcsv
cast($src_fld as DECIMAL(15,2) $tgt_fld
cast($src_fld as integer) $tgt_fld
'$default' $tgt_fld
说明您正在打印基于 FS="," 的第二个字段之后的文本部分。该脚本在打印前将其余字段附加到 $3 上。
如果如您所说,前两个字段不包含逗号,则可以使用 cut
并以逗号作为字段分隔符:
$ cut -d ',' -f 3- test.txt
cast($src_fld as DECIMAL(15,2) $tgt_fld
cast($src_fld as integer) $tgt_fld
'$default' $tgt_fld
你没有告诉我们什么是正确的输出,只是告诉我们它不是什么,所以这是对你可能想要什么的猜测,但如果这不是,你应该能够从中找出你需要什么非常正确:
$ cat tst.awk
BEGIN { FS="," }
{
[=10=] = gensub(/([(][^()]+),([^()]+[)])/,"\1"RS"\2","g",[=10=])
for (i=1; i<=NF; i++) {
gsub(RS,FS,$i)
print NR, NF, i, $i
}
print "----"
}
$ awk -f tst.awk file
1 3 1 6
1 3 2 STRING TO DECIMAL WITHOUT DEFAULT
1 3 3 cast($src_fld as DECIMAL(15,2) $tgt_fld
----
2 3 1 7
2 3 2 STRING TO INTERGER WITHOUT DEFAULT
2 3 3 cast($src_fld as integer) $tgt_fld
----
3 3 1 10
3 3 2 DEFAULT NO RULE
3 3 3 '$default' $tgt_fld
----
以上使用GNU awk 进行gensub(),其他awk 使用match()+substr()。
当你想使用循环时,可以使用
while IFS=, read -r field1 field2 rest_of_line; do
echo "Field 3: ${rest_of_line}"
done < test.txt
我有一个逗号分隔的文件,我需要从每个文件中提取第三个字段 line.File test.txt 具有以下内容:
6,STRING TO DECIMAL WITHOUT DEFAULT,cast($src_fld as DECIMAL(15,2) $tgt_fld
7,STRING TO INTERGER WITHOUT DEFAULT,cast($src_fld as integer) $tgt_fld
10,DEFAULT NO RULE,'$default' $tgt_fld
cat test.txt | awk -F, '{print }'
如果我写上面的命令,我会得到一个不正确的输出:
> cast($src_fld as DECIMAL(15
> cast($src_fld as integer) $tgt_fld
> '$default' $tgt_fld
谁能告诉我如何实现 it.I 需要写在一个循环中,以便稍后进行进一步的处理。请注意,每个第三个字段可能包含白色 space 和逗号 (,).
如果前两个字段中有逗号,则您的任务无法完成。
1,second,field,with,commas,third,field,with,commas
您无法知道第二个字段在哪里结束,第三个字段从哪里开始。
您真的必须使用实际的 CSV 语法,并使用 CSV 解析器解析文件。
1,"second,field,with,commas","third,field,with,commas"
如果你能确定前两个字段没有逗号,你可以这样做:
sed 's/^[^,]\+,[^,]\+,//' file
awk
救援!
不是通用解决方案,但适用于您的格式
$ awk -F, '{for(i=4;i<=NF;i++) = FS $i} {print }' badcsv
cast($src_fld as DECIMAL(15,2) $tgt_fld
cast($src_fld as integer) $tgt_fld
'$default' $tgt_fld
说明您正在打印基于 FS="," 的第二个字段之后的文本部分。该脚本在打印前将其余字段附加到 $3 上。
如果如您所说,前两个字段不包含逗号,则可以使用 cut
并以逗号作为字段分隔符:
$ cut -d ',' -f 3- test.txt
cast($src_fld as DECIMAL(15,2) $tgt_fld
cast($src_fld as integer) $tgt_fld
'$default' $tgt_fld
你没有告诉我们什么是正确的输出,只是告诉我们它不是什么,所以这是对你可能想要什么的猜测,但如果这不是,你应该能够从中找出你需要什么非常正确:
$ cat tst.awk
BEGIN { FS="," }
{
[=10=] = gensub(/([(][^()]+),([^()]+[)])/,"\1"RS"\2","g",[=10=])
for (i=1; i<=NF; i++) {
gsub(RS,FS,$i)
print NR, NF, i, $i
}
print "----"
}
$ awk -f tst.awk file
1 3 1 6
1 3 2 STRING TO DECIMAL WITHOUT DEFAULT
1 3 3 cast($src_fld as DECIMAL(15,2) $tgt_fld
----
2 3 1 7
2 3 2 STRING TO INTERGER WITHOUT DEFAULT
2 3 3 cast($src_fld as integer) $tgt_fld
----
3 3 1 10
3 3 2 DEFAULT NO RULE
3 3 3 '$default' $tgt_fld
----
以上使用GNU awk 进行gensub(),其他awk 使用match()+substr()。
当你想使用循环时,可以使用
while IFS=, read -r field1 field2 rest_of_line; do
echo "Field 3: ${rest_of_line}"
done < test.txt