Powershell:对列间距不均匀的文本文件进行排序
Powershell: Sorting of a text file having unevenly spaced columns
我需要对宽度和间距不均匀的文本文件进行排序,第 5 列为降序,第 6 和 7 列为升序,排序后的文件格式相同。第 7 列包含字母数字字符。
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
我知道排序对象和拆分 cmdlet,但我无法以所需的结果结束。我可以获得的附近结果来自以下命令:
get-content C:/filename.txt| For each {"$(($_ -split '\s+',10)[0..9])"}|Sort-object {$_.split(" ")[+4,+5,+6]} > newfile.txt
上面的主要问题是删除了间距以便排序,我需要相同格式的排序文件。第 7 列是字母数字,因此它的排序类似于 AB1、AB11 而不是 AB5。
以下是我认为有用的堆栈溢出链接:
Extracting columns from text file using PowerShell
PowerShell: How do I sort a text file by column?
Powershell ,Read from a txt file and Format Data( remove lines, remove blank spaces in between)
尝试这样的操作来提取所需的列并进行排序。我不认为没有多个表达式就可以组合升序和降序,所以我用一个通用的正则表达式替换了 -split
。
$data = @"
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
"@ -split [environment]::NewLine
$regex = '^(?:[^\s]+?[\s]+){4}([\w+]*?)\s+?(\w+?)\s+?(\w+?)(\d+)'
$data | Sort-Object @{expression={ if($_ -match $regex) { $Matches[1] } };Descending=$true},
@{expression={ if($_ -match $regex) { [int]$Matches[2] } };Ascending=$true},
@{expression={ if($_ -match $regex) { $Matches[3] } };Ascending=$true},
@{expression={ if($_ -match $regex) { [int]$Matches[4] } };Ascending=$true}
输出:
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
另一个解决方案,可能更容易阅读 (?)。您可以使用特定格式以您想要的方式输出Format-Table的结果:
$content = Get-Content "d:\temp\test.txt"
$table = @()
$content | %{
$line = $_
$values = $line -split '\s+'
$index = 1
$row = New-Object Object
$values | %{
$row | Add-Member -MemberType NoteProperty -Name "col$($index)" -Value $_
$index++
}
$table += $row
}
$table | Format-Table
$prop1 = @{Expression='col5'; Descending=$true }
$prop2 = @{Expression='col6'; Ascending=$true }
$prop3 = @{Expression={[regex]::Replace($values[6], '\d+',{$args[0].Value.Padleft(20)})}; Ascending=$true }
$table | Sort-Object $prop1, $prop2, $prop3 | Format-Table
另一个解决方案。首先,我定义变量:
$sb1={(${global:#$%}=($_-split'\s+'))[4]}
$sb2={${#$%}[5]}
$sb3={${#$%}[6]-replace'(\D)(\d)',"`$(' '*(16-${#$%}[6].length))`"}
然后,我使用此管道确定输出:
$lines|sort @{e=$sb1;d=$true},{&$sb2},{&$sb3},{rv '#$%' -sc 1}
发现输出是这样的:
RAXS 23173 2 4.000 QAA 235445 AB3 4IW332 1114 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 AB5 4IW332 1111 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 BB0 4IW332 1111 2/24/2015
AXSAD 23173 111191 1.000 BAA 237140 AA9 4IW332 2222 2/24/2015
GAA 43453 111190 2.000 BAA 237140 AB1 4IW332 2222 2/24/2015
DSAXS 53155 111100 1.000 BAA 237140 AB5 4IW332 3223 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB30 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB111 4IW332 2222 2/24/2015
其中 $lines
是这样定义的:
$lines=@'
GSAXS 21321 5 10.000 QAA 236333 BB0 4IW332 1111 2/24/2015
AXSAD 23173 111191 1.000 BAA 237140 AA9 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB111 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB30 4IW332 2222 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 AB5 4IW332 1111 2/24/2015
DSAXS 53155 111100 1.000 BAA 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 BAA 237140 AB1 4IW332 2222 2/24/2015
RAXS 23173 2 4.000 QAA 235445 AB3 4IW332 1114 2/24/2015
'@-split"`r`n"
我需要对宽度和间距不均匀的文本文件进行排序,第 5 列为降序,第 6 和 7 列为升序,排序后的文件格式相同。第 7 列包含字母数字字符。
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
我知道排序对象和拆分 cmdlet,但我无法以所需的结果结束。我可以获得的附近结果来自以下命令:
get-content C:/filename.txt| For each {"$(($_ -split '\s+',10)[0..9])"}|Sort-object {$_.split(" ")[+4,+5,+6]} > newfile.txt
上面的主要问题是删除了间距以便排序,我需要相同格式的排序文件。第 7 列是字母数字,因此它的排序类似于 AB1、AB11 而不是 AB5。
以下是我认为有用的堆栈溢出链接: Extracting columns from text file using PowerShell PowerShell: How do I sort a text file by column? Powershell ,Read from a txt file and Format Data( remove lines, remove blank spaces in between)
尝试这样的操作来提取所需的列并进行排序。我不认为没有多个表达式就可以组合升序和降序,所以我用一个通用的正则表达式替换了 -split
。
$data = @"
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
"@ -split [environment]::NewLine
$regex = '^(?:[^\s]+?[\s]+){4}([\w+]*?)\s+?(\w+?)\s+?(\w+?)(\d+)'
$data | Sort-Object @{expression={ if($_ -match $regex) { $Matches[1] } };Descending=$true},
@{expression={ if($_ -match $regex) { [int]$Matches[2] } };Ascending=$true},
@{expression={ if($_ -match $regex) { $Matches[3] } };Ascending=$true},
@{expression={ if($_ -match $regex) { [int]$Matches[4] } };Ascending=$true}
输出:
RASS 23173 2 4.000 Q 235445 AB5 4IW332 1114 2/24/2015
GSASS 21321 5 10.000 Q 236333 AB5 4IW332 1111 2/24/2015
GAA 43453 111190 2.000 B 237140 AB1 4IW332 2222 2/24/2015
DSASS 53155 111100 1.000 B 237140 AB5 4IW332 3223 2/24/2015
AASAD 23173 111191 1.000 B 237140 AB11 4IW332 2222 2/24/2015
另一个解决方案,可能更容易阅读 (?)。您可以使用特定格式以您想要的方式输出Format-Table的结果:
$content = Get-Content "d:\temp\test.txt"
$table = @()
$content | %{
$line = $_
$values = $line -split '\s+'
$index = 1
$row = New-Object Object
$values | %{
$row | Add-Member -MemberType NoteProperty -Name "col$($index)" -Value $_
$index++
}
$table += $row
}
$table | Format-Table
$prop1 = @{Expression='col5'; Descending=$true }
$prop2 = @{Expression='col6'; Ascending=$true }
$prop3 = @{Expression={[regex]::Replace($values[6], '\d+',{$args[0].Value.Padleft(20)})}; Ascending=$true }
$table | Sort-Object $prop1, $prop2, $prop3 | Format-Table
另一个解决方案。首先,我定义变量:
$sb1={(${global:#$%}=($_-split'\s+'))[4]}
$sb2={${#$%}[5]}
$sb3={${#$%}[6]-replace'(\D)(\d)',"`$(' '*(16-${#$%}[6].length))`"}
然后,我使用此管道确定输出:
$lines|sort @{e=$sb1;d=$true},{&$sb2},{&$sb3},{rv '#$%' -sc 1}
发现输出是这样的:
RAXS 23173 2 4.000 QAA 235445 AB3 4IW332 1114 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 AB5 4IW332 1111 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 BB0 4IW332 1111 2/24/2015
AXSAD 23173 111191 1.000 BAA 237140 AA9 4IW332 2222 2/24/2015
GAA 43453 111190 2.000 BAA 237140 AB1 4IW332 2222 2/24/2015
DSAXS 53155 111100 1.000 BAA 237140 AB5 4IW332 3223 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB30 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB111 4IW332 2222 2/24/2015
其中 $lines
是这样定义的:
$lines=@'
GSAXS 21321 5 10.000 QAA 236333 BB0 4IW332 1111 2/24/2015
AXSAD 23173 111191 1.000 BAA 237140 AA9 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB111 4IW332 2222 2/24/2015
AASAD 23173 111191 1.000 BAA 237140 AB30 4IW332 2222 2/24/2015
GSAXS 21321 5 10.000 QAA 236333 AB5 4IW332 1111 2/24/2015
DSAXS 53155 111100 1.000 BAA 237140 AB5 4IW332 3223 2/24/2015
GAA 43453 111190 2.000 BAA 237140 AB1 4IW332 2222 2/24/2015
RAXS 23173 2 4.000 QAA 235445 AB3 4IW332 1114 2/24/2015
'@-split"`r`n"