2014-11-05 2 views
0

쉬워야하지만 검색이 많이 끝나면 여전히 얻을 수 없습니다. 두 번째 슬래시 뒤에 오는 번호에 따라 다음과 같은 목록을 정렬해야합니다.두 번째 구분 기호 다음의 문자열을 기준으로 정렬 목록

/1628907159142/20141024021655 
/01_B00I7VVZAI_G6/20141028100307 
/1358737922754/20141013173229 
/1307314535151/20141023185621 
... 

이들은 타임 스탬프입니다. 처음 8 자 = 날짜. 나는 날짜순으로 가장 먼저 목록을 필요로한다. 시간은 중요하지 않습니다. Ouput은 다음과 같이 보입니다 :

/1358737922754/20141013173229 
/1307314535151/20141023185621 
/1628907159142/20141024021655 
... 

나는이 부분을 오해하고 있습니다. 나는 다음 토큰을 기반으로 정렬하는 것처럼 보이는 많은 순열을 시도했다. 저는 토큰 = 2, 토큰 = 2 *, 토큰 = 1,2, %% H %% G 등을 사용했습니다. dif만이 문자열의 어떤 부분이 파일로 들어가는지를 나타냅니다. 목록은 항상 첫 번째 슬래시 뒤에 오는 번호에 따라 정렬됩니다.

FOR /f "tokens=2 delims=/" %%G IN ('sort ^<Input.txt') DO (
    ECHO %%G >>output.txt 
) 

각 줄의 공백 뒤에 나오는 문자열을 기준으로 줄을 정렬하는 것과 같은 것을 발견했습니다. 내 경우에만 delims와 var 이름을 수정했습니다. 12 도트를 추가하고 제거하는 이유를 모르지만 그대로두고도 괜찮습니다.

지연된 확장없이 작동해야하는 것처럼 보이지만 나에게는 적합하지 않은 것처럼 보입니다. 그리고 내가 어떻게 사용하는지에 관계없이 DelayedExpansion과 함께 작동하도록 "콜 세트"를 얻을 수는 없습니다. 고맙습니다.

답변

0

토큰을 추출하기 전에 정렬 중입니다. 내장 정렬은 구분 기호에 따라 정렬하는 방법을 제공하지 않으므로 정렬 전에 입력을 다시 정렬해야합니다. 데이터를 정렬하기 위해 환경 변수를 사용하려고

del temp.txt output.txt 
FOR /f "tokens=1-2 delims=/" %%G IN (Input.txt) DO (
    ECHO /%%H/%%G >>temp.txt 
) 
sort <temp.txt >temp2.txt 
FOR /f "tokens=1-2 delims=/" %%G IN (temp2.txt) DO (
    ECHO /%%H/%%G >>output.txt 
) 
del temp.txt temp2.txt 
+0

정확히! 이제 분명해. – sjoy

+0

이중 처리를 피하려면 배치 스크립트보다 강력한 것을 사용해야합니다.:) – Miral

+0

@Miral - 사실이 아닙니다 :-) 효율적인 순수 배치 솔루션 (내 라인 수가 너무 많다고 가정)에 대한 [업데이트 된 답변] (http://stackoverflow.com/a/26768997/1012053)의 시작 부분을 참조하십시오. – dbenham

0

귀하의 영업 외 코드를 수정하기 쉽습니다 : 이런 식으로 뭔가를 시도

@echo off 
setlocal disableDelayedExpansion 

:: Clear existing _ variables 
for /f "delims==" %%A in ('set _ 2^>nul') do set "%%A=" 

:: Load the data into _ variables. 
:: The date is in the name, and the full line is in the value. 
:: A line number is included in name just in case two rows have the same date. 
:: I use FINDSTR /N to establish the line numbers. 
for /f "tokens=1* delims=:" %%A in ('findstr /n . "input.txt"') do (
    for /f "tokens=2 delims=/" %%C in ("%%B") do set "_%%C_%%A=%%B" 
) 

:: Sort and write result 
:: The SET command automatically sorts variables by name 
>output.txt (
    for /f "tokens=2 delims==" %%A in ('set _') do echo %%A 
) 

을하지만

:-) 훨씬 더 간단한 해결책이있다

주어진 토큰 위치에서 정렬 할 수 있도록 JSort.bat utility을 업데이트했습니다.

JSort.bat는 표준 Windows SORT 명령보다 훨씬 많은 기능을 제공하는 하이브리드 JScript/배치 스크립트입니다. 그것은 XP 이후부터 모든 Windows 시스템에서 기본적으로 실행되는 순수한 스크립트입니다. 전체 문서는 스크립트 내에 내장되어 있습니다.

JSort.bat는 기본 SORT 명령보다 훨씬 느리고 약 10MB의 최대 파일 크기로 제한됩니다.

JSort.bat 현재 디렉토리에, 또는 더 나은 아직, 어딘가 PATH 내 가정하면, 다음 정렬 작업은 간단 할 수있다 등 :가 있기 때문에 내가/T 3 사용

jsort input.txt /t 3 /d "/" >output.txt 

주 각 행의 시작 부분에 빈 토큰.

다음은 실제 JSort.bat 스크립트입니다. 나는이 사이트에서이 코드를 최신 상태로 유지하겠다고 약속하지 않는다. 현재 버전은 항상 DosTips에서 찾을 수 있습니다.

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment 

::************ Documentation *********** 
::JSORT.BAT version 3.2 
::: 
:::JSORT [File] [/Option [Value]]... 
::: 
::: Sort lines of text from stdin and write the result to stdout. 
::: JSORT uses an ascending, case sensitive text sort by default. 
::: 
::: File - If the optional File argument is specified, then JSORT reads lines 
:::   from the file instead of from stdin. If specified, the File must 
:::   be the very first argument. 
::: 
::: Options: 
::: 
::: /C n - Number of sorted lines to print. Skipped lines are always printed 
:::   and do not contribute to the count. Default is -1 (all lines). 
::: 
::: /D String - Specifies the string used to delimit tokens. The delimiter 
:::   string is always case sensitive. A quote literal " must be escaped 
:::   as \q, and a backslash literal \ must be escaped as \\. 
:::   The default value is an empty string, meaning treat the entire 
:::   line as a single token. 
::: 
::: /I - Ignore case when sorting 
::: 
::: /N - Sort consecutive digits as numbers instead of text. The numbers 
:::   may be embedded within alpha text. JSort supports numbers up to 
:::   20 digits long. 
::: 
::: /O File - Writes the output to File instead of stdout. 
::: 
::: /P n - Begin sorting at character position n relative to the beginning 
:::   of the selected token. Lines that do not extend that far are 
:::   treated as equivalent values, and collate before all other lines. 
:::   The default value is 1 (first character). 
::: 
::: /R - Sort the lines in Reverse (descending) order. 
::: 
::: /S n - Number of lines to skip - default is 0. 
:::   Skipped lines are not sorted (remain in place) 
::: 
::: /T n - Specify the token at which to begin sorting. The default value 
:::   is 1 (first token). 
::: 
::: /V - Display the version of JSORT.BAT. 
::: 
::: /? - Display this help 
::: 
:::JSORT.BAT was written by Dave Benham and originally posted at 
:::http://www.dostips.com/forum/viewtopic.php?f=3&t=5595 
::: 

::************ Batch portion *********** 
@echo off 
setlocal disableDelayedExpansion 

:: Get optional input file 
set "infile=" 
set "test=%~1" 
setlocal enableDelayedExpansion 
if defined test if "!test:~0,1!" neq "/" (
    endlocal 
    set ^"infile=^<"%~1"" 
    shift /1 
) else endlocal 

:: Define options 
set "options= /?: /i: /c:-1 /n: /p:1 /r: /s:0 /v: /d:"" /t:1 /o:"" " 

:: Set default option values 
for %%O in (%options%) do for /f "tokens=1,* delims=:" %%A in ("%%O") do set "%%A=%%~B" 

:: Get options 
:loop 
if not "%~1"=="" (
    setlocal enableDelayedExpansion 
    set "test=!options:* %~1:=! " 
    if "!test!"=="!options! " (
     >&2 echo Error: Invalid option %~1 
     exit /b 1 
) else if "!test:~0,1!"==" " (
     endlocal 
     set "%~1=1" 
) else (
     endlocal 
     set "%~1=%~2" 
     shift /1 
) 
    shift /1 
    goto :loop 
) 

:: Display help 
if defined /? (
    for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do echo(%%A 
    exit /b 0 
) 

:: Display version 
if defined /v (
    for /f "delims=: tokens=*" %%A in ('findstr /bc:"::JSORT.BAT version" "%~f0"') do echo %%A 
    exit /b 0 
) 

:: Transform and validate options 
set /a "case=0%/i%, num=0%/n%, pos=%/p%-1, tok=%/t%-1, order=1-2*0%/r%, 1/!(0x80000000&pos), 1/!(0x80000000&tok)" 2>nul || (
    >&2 echo Error: Invalid option value. 
    exit /b 1 
) 
set "outfile=" 
if defined /o set ^"outfile=^>"%/o%"" 

:: Perform the sort 
%infile% %outfile% cscript //E:JScript //nologo "%~f0" %case% %num% %pos% %order% %/s% %/c% %tok% "%/d%" 

exit /b 0 
************* JScript portion **********/ 
var array=new Array(), 
    nocase =WScript.Arguments.Item(0), 
    numeric=WScript.Arguments.Item(1), 
    pos =WScript.Arguments.Item(2), 
    order =WScript.Arguments.Item(3), 
    skip =WScript.Arguments.Item(4), 
    count =WScript.Arguments.Item(5), 
    token =WScript.Arguments.Item(6), 
    delim =WScript.Arguments.Item(7).replace(/\\(?!q|\\)/g,'').replace(/\\\\/g,'\\s').replace(/\\q/g,'"').replace(/\\s/g,'\\'); 
while (!WScript.StdIn.AtEndOfStream) { 
    if (skip > 0) { 
    WScript.Echo(WScript.StdIn.ReadLine()); 
    skip-=1 
    } else { 
    var expanded="", num="", raw=WScript.StdIn.ReadLine(), upper=((nocase==1)?raw.toUpperCase():raw); 
    for(var i=pos+FindToken(raw,delim,token); i<raw.length; i++) { 
     var c=upper.substr(i,1); 
     if (numeric==1 && c>="0" && c<="9") { 
     num+=c; 
     } else { 
     if (num != "") { 
      num="00000000000000000000" + num; 
      expanded+=num.substr(num.length-20); 
      num=""; 
     } 
     expanded+=c; 
     } 
    } 
    if (num != "") { 
     num="00000000000000000000" + num; 
     expanded+=num.substr(num.length-20); 
    } 
    var obj={expanded:expanded, raw:raw}; 
    array.push(obj); 
    } 
} 
if (count<0) count=array.length; 
if (count>array.length) count=array.length; 
array.sort(function(a,b){return order*((a.expanded>b.expanded)-(a.expanded<b.expanded));}); 
for (var i=0; i<count; i++) WScript.Echo(array[i].raw); 

function FindToken(str, str2, n) { 
    if (n>0 && str2=="") return str.length; 
    var rtn = 0; 
    for(var i=n; i>0; i--) { 
    rtn = str.indexOf(str2,rtn); 
    if (rtn<0) return str.length; 
    rtn+=str2.length; 
    } 
    return rtn; 
} 
+0

EDIT - Jsort 3.1로 업데이트되었습니다. 이전 버전에는 작은 버그가 있었는데 파일 경로 인수에서'! '를 다룰 수 없었습니다. 또한/O 옵션을 추가했습니다. – dbenham

+0

EDIT - JSort 3.2로 업데이트되었습니다. 버전 3.1에는 주요 인수 분석 버그가있었습니다. – dbenham

관련 문제