返回列表 发帖

[问题求助] gawk怎样排列指定字段顺序

本帖最后由 娜美 于 2023-8-10 20:54 编辑

gawk  
如果他们日期和时间分秒相同,空格视为分隔符,  如果其第5和6列字段含有指定字符串,  则根据指定字符串按先后行重新还原排列
如果日期和时间不同, 则按原排列

    例如指定要排列字符串行顺序   
    |*公司*|*企业*|*名称*|*货号*|*编号*|*品类*|


test.txt   ANSI编码文件
https://wwkt.lanzoul.com/iirP1150cxzc

回复 14# Five66


    谢谢了

TOP

回复 13# 娜美

你用bat再次试试?

TOP

本帖最后由 娜美 于 2023-8-11 14:04 编辑

回复 12# Five66


    win10系统  路径名称 没空格没任何符号

$inf="test.txt"
$otf="output.txt"

不过没所谓的    用ps1可以了

TOP

回复 11# 娜美

不可能啊,bat或者cmd都应该有输出啊,除非你的系统是win7并且路径中有方括号([,])

TOP

本帖最后由 娜美 于 2023-8-11 13:44 编辑

回复 7# Five66


   Sorry,  7楼代码使用ps1脚本有输出,     只是用bat方式没输出    谢谢哥哥

TOP

回复 9# Five66

代码默认输入文件编码是ansi,如果输入文件不是ansi编码的,可以试试修改输入文件编码 或者 修改代码 第5行,将那里得ansi改成utf8或者utf16le或者utf16be

TOP

回复 8# 娜美


    输出的文件是output.txt,只要输入文件input.txt不是空的都会有输出文件跟内容吧,运行后仔细找找看有没有output.txt,

TOP

回复 7# Five66


    将代码复制到文本  使用bat脚本执行没有输出,  运行bat脚本后也没有任何提示

    又偿试使用PS1脚本直接右键运行也没有输出
     PS版本是 5.1.19041.3031

TOP

脑子不好又不是换个编码就能解决的,gawk不会弄,弄不出来,但是用powershell弄出来了

input.txt是输入文件
output.txt是输出文件
ansi是编码,可以换成utf8,utf16le,utf16be
#@&cls&pause&powershell "gc -literalpath '%~f0'|out-string|iex"&pause&exit
$inf="input.txt"
$otf="output.txt"
$cod="ansi"
$sList=@{
"公司"=1;
"企业"=2;
"名称"=3;
"货号"=4;
"编号"=5;
"品类"=6
}
$s="公司|企业|名称|货号|编号|品类"
$inf=$pwd.path+"\"+$inf
$otf=$pwd.path+"\"+$otf
$thecod=@{
"ansi"=[text.encoding]::Default;
"utf8"=[text.encoding]::UTF8;
"utf16le"=[text.encoding]::Unicode;
"utf16be"=[text.encoding]::BigEndianUnicode
}
$a=[io.file]::ReadAllLines($inf,$thecod[$cod])
$b=[System.Collections.ArrayList]::new()
$c=[System.Collections.ArrayList]::new()
(0..($a.Length-1)).ForEach({
if($a[$_] -and ($a[$_] -match $s)){[void]$b.add(@($_,$a[$_]))}
elseif($a[$_]){[void]$c.add(@($_,$a[$_]))}
})
if(!$b -and !$c){exit}
$aa=[io.file]::OpenWrite($otf)
$aaa=[System.IO.StreamWriter]::new($aa,$thecod[$cod])
if($b){$d=[object[]]($b|group {$_[1].split(' ')[0,3] -join ''})}
$e=[object[]]($d|?{$_.count -gt 1})
if($e){
(0..($e.Count-1)).ForEach({
$e[$_].Group|sort {$tmp=[regex]::Match($_[1],$s).value;$sList[$tmp]},{$_[0]}|%{$aaa.writeline($_[1])}
$aaa.WriteLine()
})
}
$e=[object[]]($d|?{$_.count -eq 1})
if($e){(0..($e.Count-1)).ForEach({[void]$c.add(@($e[0].group[$_][0],$e[0].group[$_][1]))})}
if($c){$c|sort {$_[0]}|%{$aaa.WriteLine($_[1])}}
$aaa.close()COPY

TOP

回复 5# Five66



    test.txt 文件改为 ANSI编码  ,    不再限制必须utf16编码

TOP

回复 4# 娜美

我脑子不好,解决不了

TOP

回复 2# Five66


   哥哥这题真的没有解法了吗?

TOP

本帖最后由 娜美 于 2023-8-2 09:45 编辑

回复 2# Five66

日期和时间分秒有相同的, 并且其第5和6列字段含有指定字符串,则排列(根据指定的顺序)
日期和时间分秒没有相同的,或者其第5和6列字段含没有指定字符串,则不排列

    Yeah 理解完全正确,
  
补充一下
日期和时间分秒没有相同的, 其第5和6列字段如果含有指定字符串,则忽略不需做任何处理,  因为它们日期和时间分秒没有相同    ,(只处理日期和时间分秒相同行顺序)

TOP

相同跟不同这种描述看着挺懵的,换成有相同和没有相同感觉清楚多了

日期和时间分秒有相同的, 并且其第5和6列字段含有指定字符串,则排列(根据指定的顺序)
日期和时间分秒没有相同的,或者其第5和6列字段含没有指定字符串,则不排列

也就是按顺序从文件读入一行,然后看"有没有"跟这一行"相同"的其余行
额,好像很复杂,brain不好使,写不出code来

TOP

返回列表