我需要对宽度和间距不均匀的文本文件进行排序,第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
我知道sort-object和split cmdlet,但我无法以所需的结果结束。我能得到的附近结果来自以下命令:
get-content C:/filename.txt| For each {"$(($_ -split '\s+',10)[0..9])"}|Sort-object {$_.split(" ")[+4,+5,+6]} > newfile.txt
上面的主要问题是删除间距以便排序,我需要以相同格式排序的文件。第7列是aplhanumeric,所以它在AB5上排序为AB1,AB11。
下面是我觉得有用的堆栈溢出链接: 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)
答案 0 :(得分:1)
尝试这样的方法来提取所需的列并进行排序。我认为没有多个表达式可以将升序和降序组合在一起,所以我用一个普通的正则表达式替换了-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
答案 1 :(得分:1)
另一种解决方案,可能更容易阅读(?)。您可以使用特定格式以您希望的方式输出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
答案 2 :(得分:-1)
另一种解决方案。首先,我定义变量:
$sb1={(${global:#$%}=($_-split'\s+'))[4]}
$sb2={${#$%}[5]}
$sb3={${#$%}[6]-replace'(\D)(\d)',"`$1$(' '*(16-${#$%}[6].length))`$2"}
然后,我使用此管道确定输出:
$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"