이렇게 구조화된 파일이 있다고 가정해 보겠습니다.
/home/zz/AUTHORBOOKS/Author-Chomsky-Who-Rules-the-World.epub
/home/zz/AUTHORBOOKS/Author-Cioran-Il-nulla.epub
/home/zz/BOOKS/Author-Artemis-Mathematica-Examples.nb
/home/zz/Books/Author-Zigniwe-Hisory-Medicine.pdf
/home/z1/OLDBOOKS1/OLDBOOKS2/Author-Watanabe-Waterloo.pdf
/home/z2/OLDBOOKS1/OLDBOOKS2/Author-Barbero-Lepanto.epub.pdf
파일을 다음과 같이 정렬하고 싶습니다.
/home/zz/BOOKS/Author-Artemis-Mathematica-Examples.nb
/home/z2/OLDBOOKS1/OLDBOOKS2/Author-Barbero-Lepanto.epub.pdf
/home/zz/AUTHORBOOKS/Author-Chomsky-Who-Rules-the-World.epub
/home/zz/AUTHORBOOKS/Author-Cioran-Il-nulla.epub
/home/z1/OLDBOOKS1/OLDBOOKS2/Author-Watanabe-Waterloo.pdf
/home/zz/Books/Author-Zigniwe-History-Medicine.pdf
즉, 문자열에 따라 알파벳순으로Author-...
보시다시피 의 위치는 Author-...
일정하지 않습니다.
어떻게 해야 하나요?
답변1
다음 bash
명령을 시도해 보십시오:
sort -t- -d -k2 -o output.txt input.txt
여기에는 입력 파일 이름과 함께 네 가지 옵션이 있습니다 input.txt
. 이 파일이 현재 디렉터리에 없으면 path/to/the/folder/input.txt
. 옵션과 해당 인수는 다음과 같습니다.
- -t는 필드 구분 기호를 표시합니다.
-
구분 기호로 사용하여 앞과 뒤의 모든 항목이-
별도의 열로 간주됩니다. - -d는 사전 정렬을 나타냅니다. 예를 들어 Apple은 Berry 이전입니다.
- -k2는 정렬 기준이 되는 열(이 경우 두 번째 열)을 나타냅니다. 첫 번째 열은 첫 번째 열 이전의 모든 항목입니다
-
. 예를 들어,/home/zz/BOOKS/Author
. 두 번째 열은 첫 번째와 두 번째 열 사이-
, 즉 입니다Artemis
. - -o는
output.txt
정렬된 출력을 터미널이 아닌 파일로 리디렉션합니다.
도움이 되었기를 바랍니다
답변2
현재 예제에서는 너무 과도하지만user68186의 답변에서 제안된 솔루션, GNU awk에서 더 일반적으로 다음과 같은 작업을 수행할 수 있습니다.
gawk -F/ '
function mycmp(i1,v1,i2,v2) {
m = split(v1,a);
n = split(v2,b);
return a[m]"" > b[n]"" ? 1 : a[m]"" < b[n]"" ? -1 : 0
}
{
lines[NR] = $0
}
END {
PROCINFO["sorted_in"] = "mycmp";
for(i in lines) print lines[i]
}
' file
마지막 이후의 모든 항목의 어휘 값에 따라 정렬됩니다 /
. 따라서 형식이 Author-<author name>-<title>.<extension>
다음과 같을 경우
- 고정 문자열
Author-
(모든 행에 대해 동일한 가중치를 갖기 때문에 효과가 없음) 그 다음에 <author name>-
; 그 다음에<title>.
; 그 다음에<extension>
sort
이는 GNU 의 간단한 KEYDEF 작동 방식과 유사합니다. -t- -k2
즉, 효과적인 정렬 키는 에서 시작하여 <author name>
줄 끝까지 계속됩니다.
split
의 값을 상속하도록 호출 에서 명시적 구분 기호가 생략되므로 FS
다른 경로 구분 기호를 사용하는 시스템에서 쉽게 변경할 수 있습니다. 파일 이름이 숫자인 경우에도 함수 ""
에 추가된 빈 문자열은 어휘 비교를 강제합니다. 예를 참조하세요.mycmp
awk가 문자열과 숫자 사이를 변환하는 방법
명령 을 계속 사용하고 싶다면 sort
GNU awk를 활용할 수 있습니다.다른 프로세스와의 양방향 통신에게:
/
문자열 시작 부분에 마지막으로 구분된 필드를 복제합니다.- 결과를
sort
명령 에 전달 - 정렬된 결과를 다시 읽고, 중복된 접두사를 제거하고 인쇄합니다.
즉
gawk -F/ '
BEGIN {OFS=FS; cmd = "sort -d"}
{print $NF $0 |& cmd}
END {
close(cmd,"to");
while(cmd |& getline){$1 = ""; print};
close(cmd,"from")
}
' file
/
절대 경로(로 시작하는 줄 )가 초기 빈 필드를 암시한다는 점에서 약간의 속임수가 있습니다 . 상대 경로를 처리하려면 "누락된" 구분 기호를 삽입하기 print $NF $0
위해 변경해야 하며 , 선행 요소를 제거하려면 더 간단한 대신 print $NF,$0
정규식을 사용해야 합니다 .sub()
$1 = ""
순수 솔루션보다 잠재적으로 더 빠르고 메모리 효율성이 높을 뿐만 아니라 gawk
다른 sort
옵션을 직접 추가할 수도 있습니다. cmd = "sort -d -t " FS " -k1,1r"
.