마지막 필드를 유지하면서 Linux에서 여러 열 이름을 축약합니다.

마지막 필드를 유지하면서 Linux에서 여러 열 이름을 축약합니다.

모든 열 헤더가 경로 이름인 파일이 있습니다. 각 열 헤더를 축약하고 싶습니다.~에서다음과 같은 것 :

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample2.so.rg.mk.bam

도착하다:

sample1 sample2

Linux에서 이 작업을 어떻게 수행합니까? 내 파일에는 46~100개 이상의 열이 있으므로 열 이름을 수동으로 편집할 수 없습니다. 내가 원하는 파일 이름 길이는 위에서 언급한 대로 각각 7자입니다.

감사해요

헤더에는 파일 이름이 포함됩니다. 각 열 헤더/이름은 다음과 같습니다.

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam 

난 그냥 그 자리에 있었으면 좋겠어

sample1

명확히 하기 위해 이것은 46개의 열이 있는 텍스트 파일입니다. 각 열 헤더 또는 이름은 위의 긴 문자열로 표시됩니다. 각 헤더를 7자 버전으로 자르고 싶습니다."샘플 1"..."샘플 46"

필수 샘플 파일(각 열 헤더 아래에 데이터 포함)

sample1 sample2 sample3 sample4 sample5 ...  

답변1

원본 파일을 짧은 이름의 새 파일로 복사하는 짧은 프로그램을 작성하겠습니다. 원본 파일을 보관하면 문제가 발생할 경우 백업이 가능합니다. 작성하는 내용은 익숙한 언어에 따라 다릅니다. 이는 Bash와 같은 셸일 수도 있고 Java, C, Pearl, Python 등과 같은 모든 언어일 수도 있습니다.

다음은 몇 가지 의사 코드입니다. old는 원본 파일이고 new는 새 파일입니다. 새로 만들기

begin a loop to read each  line in old
   read line from old
   delete all characters from line up to and including the last "/"
   delete delete all characters from line after the first 7
//This is what you want to save unless it conflicts with a previously saved line
   determine if you have a conflict.
   if there is a conflict
      add a number to the end of line to make it unique
   save line to new
   end of loop

답변2

4개의 열과 2개의 행이 있는 파일이 있다고 가정해 보겠습니다.

host:~ # cat file2
/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample2.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample3.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample4.so.rg.mk.bam
abc def ghi jkl

이 명령은 저에게 효과적입니다(매우 편리하지는 않지만 여전히).

host:~ # sed -i -e 's/^\///g' -e 's/[[:alnum:]]\+\///g' -e 's/\.[[:alnum:]]\+//g' -e 's/\///g' file2
host:~ # cat file2
sample1 sample2 sample3 sample4
abc def ghi jkl

더 효율적인 방법이 있다고 확신하지만 시도해 볼 수 있습니다.

답변3

원하지 않는 접미사는 항상 있다고 가정합니다.".so.rg.mk.bam", 그 다음에암소 비슷한 일종의 영양 sed~의e평가주문하다basename첫 번째 줄에서만 실행하는 데 사용할 수 있습니다파일 이름, 원하는 출력으로 바꿉니다.

sed -i '1s/.*/basename -as .so.rg.mk.bam -a &/e' filename

~을 위한GNU가 아닌 seds를 head대신 사용할 수 있습니다.

sed -i '1s/.*/'"$(basename -as .so.rg.mk.bam -a $(head -1 filename))"'/' filename

--

참고: 파일을 변경하지 않고 결과를 보려면 먼저 파일을 변경하지 않고 시도해 보세요 -i.

답변4

awk를 사용하여 헤더를 처리할 수 있습니다. 다음 awk 스크립트가 작동합니다오직첫 번째 줄 ( NR==1). 행의 모든 ​​필드를 한 번에 반복합니다. 각 필드에 대해 다음 단계를 수행합니다.

  1. 텍스트의 첫 번째 인스턴스를 찾아 /sample해당 인스턴스로 텍스트를 자릅니다(및 전달 /).
  2. 기간의 나머지 부분에서 첫 번째 인스턴스를 찾아 해당 기간부터 시작하여 해당 부분을 정리합니다.
  3. 나머지 부분이 너무 길면 sample필요에 따라 텍스트를 자릅니다. 얼마나 유지해야 하는지에 대한 방정식은 "6 더하기 첫 번째 숫자의 위치 - 전체 길이"입니다.
  4. 필드를 처리한 후 후행 공백을 포함하여 인쇄합니다.
  5. 모든 필드에 대한 반복이 끝나면 개행 문자를 인쇄합니다.

이렇게 하면 줄 끝에 후행 공백이 남습니다.

awk 스크립트:

NR == 1 {
  for(i=1; i <= NF; i++) {
    tail=substr($i, 1 + match($i, "/sample"))   # delete up to the first instance of "/sample"
    tail=substr(tail, 1, index(tail, ".") - 1)  # find, then stop short of, the first period
    if (length(tail) > 7) {                     # if it's too long
        match(tail, "[0-9]")                    # find the first digit
                                                # trim the beginning down, then append the number
        tail=substr(tail, 1, 6 + RSTART - length(tail))substr(tail, RSTART)
    }
    printf tail" "
  }
  print ""
}

샘플 입력:

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample47.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample4631.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample1234567.so.rg.mk.bam 

예시 출력은 다음과 같습니다:

sample1 sampl47 sam4631 1234567

관련 정보