仅从 TSV 文件中的双引号字符串中删除制表符?
Remove tabs only from within double-quoted strings in TSV file?
我有一个 TSV 文件,经过进一步检查,有时在某些行的双引号字符串字段的 some 中包含制表符(似乎在各种字符串字段中任意发生)并想在 bash 中删除这些。例如。在 vi
中查看带有 :set list
的文件时,我看到类似...
的内容
1234^I"some^Itext field"^I"more text"^I4678^I"other^Itext here"$
并且想要得到类似...
1234^I"some text field"^I"more text"^I4678^I"other text here"$
有人知道如何在 bash 中有效地完成这项工作吗?
这不是最可靠的解决方案,但也许您可以将其用作起点。
sed -e 's/\("[^\t"]*\)\t\([^\t"]*\)"/ /g' tsv_file.txt
我认为一个合适的解决方案需要一个小型文本解析器,它可能最好用 Perl 或 Python 等语言编写。
如果你有 GNU awk,你可以使用它的 FPAT
变量将每一行分成字段,然后使用 gsub
编辑它们:
gawk -v OFS='\t' -v FPAT='"(""|[^"]*)*"|[^\t]*' '
{
for (i=1; i<=NF; i++)
gsub(/\t/, " ", $i)
print
}
' in.tsv > out.tsv
OFS
设置为制表符,以便 print
生成制表符分隔的输出。
我在这里给出的 FPAT 值将字段定义为:
- 双引号
- 后跟任意数量的:
- 两个双引号
- 或任意数量的不是双引号的字符
- 后跟双引号
或:
- 任意数量的非制表符
请注意,gawk 无法处理字段中嵌入的换行符。
参见:https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html
我有一个 TSV 文件,经过进一步检查,有时在某些行的双引号字符串字段的 some 中包含制表符(似乎在各种字符串字段中任意发生)并想在 bash 中删除这些。例如。在 vi
中查看带有 :set list
的文件时,我看到类似...
1234^I"some^Itext field"^I"more text"^I4678^I"other^Itext here"$
并且想要得到类似...
1234^I"some text field"^I"more text"^I4678^I"other text here"$
有人知道如何在 bash 中有效地完成这项工作吗?
这不是最可靠的解决方案,但也许您可以将其用作起点。
sed -e 's/\("[^\t"]*\)\t\([^\t"]*\)"/ /g' tsv_file.txt
我认为一个合适的解决方案需要一个小型文本解析器,它可能最好用 Perl 或 Python 等语言编写。
如果你有 GNU awk,你可以使用它的 FPAT
变量将每一行分成字段,然后使用 gsub
编辑它们:
gawk -v OFS='\t' -v FPAT='"(""|[^"]*)*"|[^\t]*' '
{
for (i=1; i<=NF; i++)
gsub(/\t/, " ", $i)
print
}
' in.tsv > out.tsv
OFS
设置为制表符,以便 print
生成制表符分隔的输出。
我在这里给出的 FPAT 值将字段定义为:
- 双引号
- 后跟任意数量的:
- 两个双引号
- 或任意数量的不是双引号的字符
- 后跟双引号
或:
- 任意数量的非制表符
请注意,gawk 无法处理字段中嵌入的换行符。
参见:https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html