仅从 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