각 마지막 줄에 일련 번호를 생성하십시오. 게시물이 수정되었습니다. 누구든지 이에 대한 도움과 조언을 제공할 수 있습니까?

각 마지막 줄에 일련 번호를 생성하십시오. 게시물이 수정되었습니다. 누구든지 이에 대한 도움과 조언을 제공할 수 있습니까?

이 쿼리가 있습니다

sed '/./=' abc.txt| sed '/./N; s/\n/, /' >> as.dat


source file has 3 rows like below
a
b
c

다음 명령을 사용하면 다음과 같은 결과가 나타납니다.

Output 

    1 a
    2 b 
    3 c 

하지만 나는 다음과 같은 명령 출력을 원합니다.

Output 

    a 1 
    b 2 
    c 3 

답변1

cut유닉스에는 and 라고 불리는 멋진 작은 도구가 있습니다 paste. 이 cut도구는 열을 삽입하는 동안 입력에서 열 집합을 추출합니다 paste. 우리는 이것을 사용할 것입니다.

나는 귀하의 파이프라인에 대해 별로 신경 쓰지 않고(지금은 이 답변의 끝 부분을 참조하십시오) 열 전환 문제에만 관심이 있습니다.

다음과 같은 파일에 데이터가 있다고 가정해 보겠습니다 cols.txt.

$ cat cols.txt
1 a
2 b
3 c

$ paste -d ' ' cols.txt cols.txt
1 a 1 a
2 b 2 b
3 c 3 c

유틸리티는 paste일반적으로 열 사이에 탭 문자를 삽입하지만 여기서는 공백( -d ' ')을 삽입하도록 지시합니다.

paste그런 다음 with 출력에서 ​​두 번째와 세 번째 열을 추출합니다 cut.

$ paste -d ' ' cols.txt cols.txt | cut -d ' ' -f 2,3
a 1
b 2
c 3

cut우리 는 "필드 구분자"( , 그렇지 않으면 탭이 필요함)로 공백이 있고 필드 2와 3( ) -d ' '을 갖고 싶다고 말했습니다 . -f 2,3(아쉽게도 원래 입력의 cut" " 열만 필요합니다.2,1아니요열을 교환합니다. )

따라서 궁극적으로 여기서는 지저분한 정규식 마술이 필요하지 않습니다.

파이프라인으로 돌아가세요. 스크랩해봅시다. 각 행에 행 번호를 삽입하려는 것 같습니다. nl("numberline") 이라는 또 다른 Unix 도구가 있습니다 .

$ nl abc.txt
     1  a
     2  b
     3  c

기본적으로 비어 있지 않은 각 줄의 줄 번호를 가져옵니다. 앞에는 패딩을 위한 공백이 있고 탭으로 원래 줄과 구분됩니다. 빈 줄에도 번호를 매기시겠습니까?

$ nl -b a abc.txt

내가 아는 한 nl행 오른쪽에 행 번호를 넣을 수는 없지만 입력의 두 열을 바꾸는 솔루션이 있으므로 문제가 되지 않습니다.

$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a            1
b            2
c            3

여기서는 더 이상 구분 기호를 지정할 필요가 없습니다. nl각 줄의 시작 부분에 공백이 삽입되고 그 뒤에 줄 번호와 탭 문자가 삽입됩니다. paste열 사이에 탭을 삽입하고 cut탭을 자르면 작동합니다.

열 사이에 공백을 원하면(이제 탭과 일부 공백이 있음) 이를 | tr -s '\t' ' '명령에 추가하십시오. 이는 모든 탭 문자를 공백으로 변경("음역")하고 -s결과로 나오는 연속 공백을 단일 공백으로 "압축"( )합니다.

쉼표와 공백을 원하면 다음을 사용하십시오 | tr '\t ' ', '.

$ paste  <(nl abc.txt) <(nl abc.txt) | cut -f 2,3 | tr -s '\t ' ', '
a, 1
b, 2
c, 3

이는 한 줄에 여러 단어가 포함된 파일에는 작동하지만 탭 문자가 포함된 파일에는 실패합니다.

$ cat abc.txt    # no tabs in this file though
a text     there is a
b goes     hole in my
c here     pants

$ paste  <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a text     there is a        1
b goes     hole in my        2
c here     pants             3

답변2

sed '/./=' | sed '/./{N; s/\(.*\)\n\(.*\)/\2 \1/;}'

그러나 awk더 직접적일 것입니다:

awk '/./ {$0 = $0 " " NR}; {print}'

최소한 하나의 문자가 포함된 줄에만 번호를 매기는 것이 이상해 보입니다. 이것이 의도하지 않은 경우 다음과 같이 변경할 수 있습니다.

sed = | sed 'N; s/\(.*\)\n\(.*\)/\2 \1/'
awk '{print $0, NR}'

답변3

작업을 수행하는 또 다른 방법은 nloptions 와 함께 명령을 사용하는 것입니다 -nln. 이는 파일의 행에 번호를 매깁니다. 예를 들어..

echo -e "a\nb\nc\n" | nl -nln -

생산 예정:

 1  a
 2  b
 3  c

이제 남은 것은 숫자를 단어 오른쪽으로 옮기는 것뿐입니다. 이는 다음을 sed사용하여 수행할 수 있습니다.

sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'

그것이 하는 일은 줄의 첫 번째 단어를 찾는 것입니다. (첫 번째 단어를 찾으려면 공백과 탭을 제외한 문자만 포함해야 합니다. 이는 를 사용하여 수행됩니다. [^ \t]) 공백과 함께 기억합니다 . \1다음 줄은 부분적 \2으로 및 로 대체 됩니다 \2 \1.

그래서 마지막 명령은

cat filename | nl -nln - | sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'

관련 정보