2012-12-20 3 views
4

이 겉으로는 복잡한 작업에 대한 쉬운 해결책이 있는지 궁금 해요 :쉬운 솔루션

lineone 
linetwo 
linethree 
linefour 

lineone 
linetwo 
linethree 
linefour 

lineone 
lineone 
lineone 
linetwo 
linethree 
linefour 

당신을 생각할 수있는 간단한 방법이 있나요 :

내가이 파일이 말은 이 결과를 얻을 :

lineone[1] 
linetwo[1] 
linethree[1] 
linefour[1] 

lineone[2] 
linetwo[2] 
linethree[2] 
linefour[2] 

lineone[3] 
lineone[4] 
lineone[5] 
linetwo[3] 
linethree[3] 
linefour[3] 

단어에 넣어, 나 숫자가 파일에 선두로부터의 순으로 각 행 할 것입니다 간단한 bash는 알고리즘이있다? 추가 스토리지가 포함 된 복잡한 솔루션이 없으면이를 수행 할 수있는 방법을 찾지 못했습니다. 여기서 라인 교체에 사용하는 일반적인 명령은 쓸모가 없습니다. sed는 모든 발생 라인을 동일한 값으로 대체 할 것이고 replace ($ {string/substring/replace}) 문자열은 라인의 순서를 유지하지 않으므로 도움이되지 않습니다.

매우 감사드립니다.

+0

명확히하기 위해 숫자는 줄의 내용 만 기반으로하며 줄의 텍스트 블록을 기반으로하지 않습니다. 그래서 만약 당신이'lineone \ nlineone \ nlineone'을 가지고 있다면 당신은'lineone [1] \ nlineone [2] \ nlineone [3]'을 얻을 것입니까? –

+0

[X/Y 문제] (http://meta.stackexchange.com/questions/66377/what-is-the-xy)가 될 수 있으므로 실제 데이터를 제공하면 대답하는 것이 더 쉽습니다. -문제). –

+0

@ F.J. 예. 첫 번째 진술이 정확합니다. 숫자는 행의 내용을 기반으로합니다. 나는 혼란에 대해 사과합니다, 나는 상대적으로 배쉬를 처음 접했습니다. –

답변

3

다음 awk 명령은 줄 배열과 개수를 유지하여 작동합니다.

awk '{if($0~/./){a[$0]++;print $0"["a[$0]"]";} else print}' file 

예 :

$ cat file 
lineone 
linetwo 
linethree 
linefour 

lineone 
linetwo 
linethree 
linefour 

lineone 
linetwo 
linethree 
linefour 

lineone 
lineone 
lineone 
linetwo 
linethree 
linetwo 

$ awk '{if($0~/./){a[$0]++;print $0"["a[$0]"]";} else print}' file 
lineone[1] 
linetwo[1] 
linethree[1] 
linefour[1] 

lineone[2] 
linetwo[2] 
linethree[2] 
linefour[2] 

lineone[3] 
linetwo[3] 
linethree[3] 
linefour[3] 

lineone[4] 
lineone[5] 
lineone[6] 
linetwo[4] 
linethree[4] 
linetwo[5] 
+0

하나 이상의 공백 만 포함하는 모든 행과도 일치합니다. awk '{if ($ 0'\! '~/^ [] * $ /) {a [$ 0] ++; print $ 0 "[awk' "[$ 0]"] ";} else print} '''\!'주위의 인용 부호는'! '문자로 인한 이상한 이스케이프 문제 때문입니다. – Sammitch

2

빠른 100 % 순수 bash는 대답은 :

#!/bin/bash 

declare -A lines=() 
while read -r l; do 
    if [[ -n "$l" ]]; then 
     echo "$l[$((++lines[$l]))]" 
    else 
     echo "$l" 
    fi 
done < file.txt 

이,하는 간단한 bash는 알고리즘을 필요로 할 것이다되는 [당신] 수를 각각 [비어 있지 않은] 행은 파일의 발생 순서대로입니다.

그것은 가장 빠른 방법이 아니다합니다 (awk 대답은 빠르고 효율적이지만 awk 대답은 bash는 알고리즘하지 않습니다).

트릭은 키가 파일의 줄인 연관 배열 lines을 사용하고 비어 있지 않은 행을 읽을 때마다 해당 키의 값을 증가시키는 것입니다.

아니면 그랜드 어머니를 인상 할 수 있도록 한 라이너 :

declare -A lines=(); while read -r l; do [[ -n "$l" ]] && echo "$l[$((++lines[$l]))]"; || echo "$l"; done < file.txt 
+0

왜 배열이 필요한지 잘 모르겠습니다. 대신 간단한 카운터를 사용하여 1로 초기화하고 빈 줄이 표시되면이를 증가시킵니다. – chepner

+0

@chepner : 빈 줄이 나타날 때마다 증가시켜야하는 카운터가 아닙니다. 대신 파일의 순서대로 각 행을 _ 행합니다. dogbane의 예제 출력을 참조하십시오. –

+0

당신 말이 맞아요. 나는 조심스럽게 원하는 결과를 읽지 못했습니다. – chepner

2

탐색 도중 틱 펄 한 줄 :

perl -00 -lpe 's/$/"[". $. . "]"/gem' 

내가 질문을 잘못 이해 참조 모호한 예를 기반으로합니다. 설명 된대로 줄 번호를 매기는 Perl 스 니펫은 다음과 같습니다.

+0

질문에 대한 오해가 있었기 때문에이 답변을 upvoted했습니다. 그러나 올바르지 않다는 것을 깨달았습니다. 단락 수만 계산하고 줄 반복 횟수는 계산하지 않습니다. – Idelic

+0

@ 아이 딕, 알겠습니다, 고마워요. –

+0

둘 다 아름다워요! – Idelic