Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 使用带空值的命令按三列对csv文件排序?_Windows_Sorting_Csv_Batch File_Command Line - Fatal编程技术网

Windows 使用带空值的命令按三列对csv文件排序?

Windows 使用带空值的命令按三列对csv文件排序?,windows,sorting,csv,batch-file,command-line,Windows,Sorting,Csv,Batch File,Command Line,情况是这样的: 我有一个csv文件,有6列,没有标题,如下所示: 5002200,25081,0000002797,6,,2014/06/05 5001111,25081,0000002790,,,2014/06/05 5004901,00081,0000002799,5,,2014/06/05 5004901,00081,0000002796,5,,2014/06/05 我想要的输出经过排序后显示如下: 5001111,25081,0000002790,,,2014/06/05 5002

情况是这样的:

我有一个csv文件,有6列,没有标题,如下所示:

5002200,25081,0000002797,6,,2014/06/05
5001111,25081,0000002790,,,2014/06/05
5004901,00081,0000002799,5,,2014/06/05 
5004901,00081,0000002796,5,,2014/06/05

我想要的输出经过排序后显示如下:

5001111,25081,0000002790,,,2014/06/05
5002200,25081,0000002797,6,,2014/06/05  
5004901,00081,0000002796,5,,2014/06/05 
5004901,00081,0000002799,5,,2014/06/05 

问题是缺少空值。有什么想法吗

我的算法是对第一列和第三列进行排序,然后显示为原始位置。但是,如果有任何空值(如第4列或第5列),它将丢失。

第一列始终包含7个长度。
只有第4列或第5列将包含空

sort /+8 infilename >outfilename
看起来会做你想做的事。也许如果你能清楚地解释一下你的排序算法,我们就能构建一个更合适的系统


@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
设置“destdir=U:\destdir”
设置“filename1=%sourcedir%\q36542742.txt”
设置“outfile=%destdir%\outfile.txt”
设置“tempfile=%destdir%\tempfile.txt”
删除“%tempfile%”>NUL 2>NUL
(
::第一步-为每行编号,编号为%%a,编号为%%b
对于/f“skip=1tokens=1*delims=[]”中的%%a('find/n/v”“%filename1%”)DO(
REM令牌行-需要的零件到%%p、%%q
对于/f“tokens=1,3delims=,”%%p IN(“%%b”)DO(
REM构造排序记录
呼叫:处理%%p%%q%%a%%%b
)
)
对于/f“tokens=1*delims=“%%a IN('sort”%tempfile%%'),执行回显(%%b
)>“%outfile%”
删除“%tempfile%”>NUL 2>NUL
后藤:EOF
::第一个参数:主排序标准(固定长度)
::第二:二级排序标准(引入零抑制数字)
::第三:引用数据
:进程
设置/a$line=100000000+%2
>>“%tempfile%”回显(%1%$line%%~3
后藤:EOF
您需要更改
sourcedir
destdir
的设置以适应您的环境

我使用了一个名为
q36542742.txt
的文件,其中包含用于测试的数据

生成定义为%outfile%的文件

tempfile
可以设置为您喜欢的任何设置

首先,通过
find
发送文件,查找不包含任何内容的行并对其编号。因此,每行都将成为

[number]originallinedata
通过使用每行以数字开头的事实在
[]
上标记,
%%a
将被设置为行号,
%%b
将被设置为行数据

重新处理行数据,使用
标记和拾取标记1和3。这两个字段的长度都是固定的,第二个标记不能为空

通过以下过程处理该行:
:处理
提供串联的参数\u column1\u column3 line\u number originaldataline

:处理
,将100000000添加到
%2
中的行号,然后发送

串联列1列3修改行数SpaceOriginalDataline

所以发送的线路是

500220000000027971000000001 5002200,25081,0000002797,6,,2014/06/05
空间前的线部分为固定长度


完成后,对tempfile进行排序,并在第一个空格后报告零件。

如果输入文件和输出文件不同,只需使用Unxutil命令排序一行

gawk -F"," "{print $1,$2,$3,$4,$5,$6}" input.csv|sort -gk1,3|sed "s/ /,/g";"s/$/\r/">output.csv
如果输出是直接输入文件,例如,input.csv文件可以通过将自身拖动到批处理文件中来获得结果

sed -i "s/,/ /g" "%~1"
sort -gk1,3 "%~1" -o"%~1"
sed -i "s/ /,/g";"s/$/\r/" "%~1"
exit /b

每个列都可以保留为原始列。

以下脚本能够满足您的请求(我们称之为
排序csv.bat
):

@echo关闭
setlocal EnableExtensions EnableDelayedExpansion
rem定义常量:
设置“infle=%~1”
设置“输出文件=%~2”
将“TEMPFILE=%TEMP%\%~n1\u临时\u设置为\u排序%%x1”
设置/A最大宽度=10
如果不存在“!infle!”退出/B 1
如果未定义输出文件集“输出文件=%~dpn1\u排序的%%x1”
设置“PADZEROS=”
对于(1,1,%MAXWIDTH%)中的/L%%$设置“PADZEROS=!PADZEROS!0”
>“!TEMPFILE!”(
对于/F“delims=“%%”in('findstr/N/R“^^^”!infle!”)do(
设置“行=%%”&设置“行=!行:*=!”
对于/F“delims=:”(“%%#”)中的%%a,请设置“LNUM=!PADZEROS!%%a”
对于/F“tokens=1,3 delims=,”%%A in(“!LINE:^,^=”,“!”)do(
设置“ITEM1=!PADZEROS!%%~A”&设置“ITEM1=!ITEM1:~-%MAXWIDTH%”
设置“ITEM2=!PADZEROS!%%~B”&设置“ITEM2=!ITEM2:~-%MAXWIDTH%”
回显(!ITEM1!;!ITEM2!;!LNUM:~-%MAXWIDTH%!!!行!
)
)
)
>“!OUTFILE!”(
对于/F“tokens=1,*delims=\%%I in('sort“!TEMPFILE!”)do(
回声(%%J
)
)
>nul 2>&1删除“!临时文件!”
端部
退出/B
要使用此批处理文件,请提供输入和输出路径/文件作为命令行参数:

这背后的主要思想是将每个分隔符
替换为
,“
,并将
中的每一行括起来,这样每个项目都会括在
中;例如,像
1,2,4这样的行会变成
“1”,“2”,“4”
。这避免了相邻的分隔符
,因此,可以使用带有
作为分隔符的
for/F
循环来获取项目;
~
for/F
变量的
修饰符用于删除周围的

对于排序,使用一个临时文件,其中包含以(分号分隔的)列为前缀的原始行,用于排序,以及以前导零填充方式填充的原始行号。因此,您的输入文件变为:


然后,该文件被送入
sort
命令,其输出被另一个
for/F
循环捕获,该循环会切断前缀,这是
\uUcode>字符的全部内容。

如果不使用单个标记,为什么要拆分为标记?请改用整行。我是cmd脚本的新手。请显示me?谢谢,第一列并不总是包含8个长度。你的意思是什么?脚本没有生成输出文件吗?使用示例数据,它对我有效;请注意,我修复了脚本文件名(它被称为
sort csv.bat
而不是
sort\u csv.bat
)…我修复了它。但是你能不能编辑一些代码,让输入是一个文件,输出在这些文件中排序。要覆盖
sed -i "s/,/ /g" "%~1"
sort -gk1,3 "%~1" -o"%~1"
sed -i "s/ /,/g";"s/$/\r/" "%~1"
exit /b
sort-csv.bat "input-file.csv" "output-file.csv"
0005002200;0000002797;0000000001_5002200,25081,0000002797,6,,2014/06/05
0005001111;0000002790;0000000002_5001111,25081,0000002790,,,2014/06/05
0005004901;0000002799;0000000003_5004901,00081,0000002799,5,,2014/06/05
0005004901;0000002796;0000000004_5004901,00081,0000002796,5,,2014/06/05