csv PowerShell脚本,仅替换用双引号括起来的子字符串中的制表符

yqkkidmi  于 2023-07-31  发布在  Shell
关注(0)|答案(4)|浏览(131)

我正在处理一个制表符分隔值(tsv)文本文件。我将其导入Excel,但出于某种原因,它也将字符串中的制表符(用双引号表示)视为分隔符。
文件中的一行看起来像这样:

Name  Quote  Random text
Harry  "I like putting    tabs in sentences"  "Here is another tab   "

字符串
我试着写一个powershell脚本来读取整个文本文件,只找到用引号括起来的制表符,然后用空格符替换它们。我知道这是可能的,但问题是我不是PowerShell或regex的Maven:D
有什么想法吗

toiithl6

toiithl61#

试试这个-

(Get-Content \\PathToYourTextFile\TabFile.txt).Replace("`t", " ")

字符串

或者

Get-Content \\PathToYourTextFile\TabFile.txt | % {$_ -replace ("`t", " ")}


两者都将文本文件中的tabs替换为单个空格。

izj3ouym

izj3ouym2#

如果你想用空格完全替换制表符,请使用Vivek Kumar Singh提供的解决方案。
但是,如果您想将其保留为TSV,则可以将其导入变量,用空格替换制表符(仅在值中),然后导出:

$content = Import-Csv .\file.tsv -Delimiter "`t"
foreach ($line in $content) {
    $line.Name = $line.Name.replace("`t", " ")
    $line.Quote = $line.Quote.replace("`t", " ")
    $line.'Random text' = $line.'Random text'.replace("`t", " ")
}
$content | Export-Csv .\output.tsv -Delimiter "`t" -NoTypeInformation

字符串
顺便说一句,这可能不需要,因为我对我的Excel导入数据正确。也许是文件/特定行的问题?

s3fp2yjn

s3fp2yjn3#

在替换命令中使用Hex values作为引号和水平制表符

(gc "\\Path to Your\file") -replace "[\x22][\x09][\x22]"," " | set-content "\\Path to Your\file"

字符串

vsnjm48y

vsnjm48y4#

Robert Dyjas有一个很好的答案,但是我想扩展他的答案,并使替换动态,而不必显式地调用每个字段。相反,下面的版本做了两件事:
1.首先,它检查每一个字段,并取代双引号,制表符,回车和新行字段内,最后它修剪。注意:制表符将替换为空格,而字段中的所有其他字符将替换为空白。
1.其次,它扫描每个字段并检查它是否是有效的日期。在这一点上,你可以做任何处理是需要对这些日期字段,但在我的版本下面,以插入我的数据到一个SQL Server数据库,我的所有日期需要有年大于1900年,由于SQL Server最低年为1753年(我选择了1900年)。
为了实现这一点,我改为使用ForEach-Object和管道$content通过。

$content = Import-Csv .\file.tsv -Delimiter "`t"
$content |
ForEach-Object {

    foreach ($property in $_.PSObject.Properties)
    {
        if ( ![string]::IsNullOrEmpty($property.Value)  ) {
            # Replace Double Quotes, Tabs, Carriage Returns and New Lines within Fields and Trim.  Note: TABs are replaced with a space.
            $property.Value = $property.Value -replace '\"','' -replace "`t",' ' -replace "`r",'' -replace "`n",''
            $property.Value = $property.Value.Trim()
            
            # Scan fields for dates.  If a Date is found make sure the Year is greater than 1900.  If not update the year to 1900
            if ( ( $property.Value -as [datetime] ) -and ( [datetime]$property.Value -lt (Get-Date 1900-01-01) ) ) {
                $property.Value = (Get-Date $property.Value -Year 1900).ToString('yyyy-MM-dd')
            }
        }
    }
} |
Export-Csv .\output.tsv -Delimiter "`t" -NoTypeInformation

字符串

相关问题