n과 m 구분 기호 사이의 하위 문자열 추출

n과 m 구분 기호 사이의 하위 문자열 추출

파일 목록의 세 번째와 네 번째 /사이의 모든 항목을 가져오기 위해 for 루프를 작성하고 싶습니다..

내 시도:

for mcool_file in ./input/*.mcool; do
    while IFS= read -r id; do
        id | cut -d \\ -f 4- -d_ -f1-4
        # Do something
    done;
done

역 추적:

cut: only one type of list may be specified

입력하다

./../input/A001C007.hg38.nodups.pairs.mcool
./../input/A001C008.hg38.nodups.pairs.mcool

원하는 출력

A001C007
A001C008

답변1

for pathname in input/*.mcool; do
    basename "${pathname%%.*}"
done

의 각 경로 이름에 대해 input경로 이름은 표준 인수 대체( 값에서 패턴과 일치하는 가장 긴 접미사 문자열 제거)를 사용하여 첫 번째 지점에서 잘린 다음 경로 를 추출하는 데 사용됩니다. 이름의 이름 부분..mcool$pathname${pathname%%.*}.*$pathnamebasename

시험:

$ tree
.
`-- input
    |-- A001C001.something.mcool
    |-- A001C002.something.mcool
    |-- A001C003.something.mcool
    |-- A001C004.something.mcool
    |-- A001C005.something.mcool
    |-- A001C006.something.mcool
    |-- A001C007.something.mcool
    |-- A001C008.something.mcool
    `-- A001C009.something.mcool

2 directories, 9 files
$ for pathname in input/*.mcool; do basename "${pathname%%.*}"; done
A001C001
A001C002
A001C003
A001C004
A001C005
A001C006
A001C007
A001C008
A001C009

이는 첫 번째 점이 $pathname경로 이름의 디렉토리 부분이 아닌 파일 이름에 나타난다고 가정하므로 ./.

basename그러나 이를 먼저 호출하여 디렉토리 경로에 점이 포함되도록 이를 반대로 할 수 있습니다.

for pathname in ./input/*.mcool; do
    name=$(basename "$pathname")
    printf '%s\n' "${name%%.*}"
done

만약 우리가알다제거하려는 접미사 문자열은 정확히 문자열 .something.mcool(또는 .hg38.nodups.pairs.mcool귀하의 경우)이며, 가장 좋은 해결책은 다음과 같습니다.

for pathname in ./input/*.something.mcool; do
    basename "$pathname" .something.mcool
done

basename... 경로 이름에서 알려진 접미사를 제거하고 경로 이름의 파일 이름 부분을 한 번에 하나씩 반환하는 데 사용됩니다 .

basename여러 파일을 처리하고 각 파일에서 고정 접미사 문자열을 제거하기 위한 비표준 -a및 옵션을 지원하는 구현을 사용하면 -s처리할 파일이 너무 많지 않은 경우 루프를 전혀 사용할 수도 없습니다.

$ basename -a -s .something.mcool ./input/*.something.mcool
A001C001
A001C002
A001C003
A001C004
A001C005
A001C006
A001C007
A001C008
A001C009

basename(1)시스템의 설명서를 참조하십시오 .

답변2

그리고 zsh:

print -rC1 -- input/*.mcool(N:t:r:r:r:r)

( :t수정자를 사용하면 다음을 얻을 수 있습니다.꼬리, :r게다가뿌리(csh나 vim처럼 파일 확장자를 제거하세요.)

또는:

set -o histsubstpattern
print -rC1 -- input/*.mcool(N:t:s/.*//)

또는:

(){print -rC1 -- ${@/.*}} input/*.mcool(N:t)

( ${var/pattern[/replacement]}csh-style 대신 ksh-style을 사용하십시오 :s/foo/bar/. 익명 함수에 전달된 인수에 대해서는 여기에서 ksh를 참조하십시오 ${@%%.*}.)

답변3

모든 입력이 다음과 같다면

./../input/A001C007.hg38.nodups.pairs.mcool

그렇다면 가장 간단한 방법은 아마도 다음과 같습니다.

start cmd:> sed -e 's+^./../input/++' -e 's/\..*$//' input
A001C007
A001C008

/.세 번째부터 다음까지 모두 삭제하고 싶다면

start cmd:> sed -r -e 's+^([^/]*/){3}++' -e 's/\..*$//' input
A001C007
A001C008

설명하신 일반적인 솔루션은 .수량을 세 번째까지 계산해야 합니다 /.

답변4

/세 번째 와 네 번째 라는 것을 알고 있는 경우 및 구분 기호를 기반으로 필드를 정의 .할 수도 있습니다 .awk/.

awk -F'[./]' '{print $7}'

관련 정보