Program Club

Unix에서 경로의 일부 제거

proclub 2021. 1. 5. 08:20
반응형

Unix에서 경로의 일부 제거


문자열에서 경로의 일부를 제거하려고합니다. 나는 경로가 있습니다.

/path/to/file/drive/file/path/

첫 번째 부분을 제거 /path/to/file/drive하고 출력을 생성하고 싶습니다 .

file/path/

참고 : while 루프 /path/to/file/drive에는 모두 동일한 경로가 있지만 원하는 문자열을 제거하는 방법에 대한 '방법'을 찾고 있습니다.

몇 가지 예를 찾았지만 작동시킬 수 없습니다.

echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:\2:'
echo /path/to/file/drive/file/path/ | sed 's:/path/to/file/drive:2'

\2 문자열의 두 번째 부분이고 나는 분명히 뭔가 잘못하고 있습니다 ... 어쩌면 더 쉬운 방법이 있습니까?


POSIX 쉘 변수 확장을 사용하여이를 수행 할 수도 있습니다.

path=/path/to/file/drive/file/path/
echo ${path#/path/to/file/drive/}

#..일부 변수가 확장 최고의 매칭 문자열을 스트립; 이것은 for루프를 사용하는 경우처럼 문자열이 이미 쉘 변수에있는 경우 특히 유용합니다 . 를 사용하여 변수 끝에서 일치하는 문자열 (예 : 확장명)을 제거 할 수도 있습니다 %.... 자세한 내용은 bashman 페이지를 참조 하십시오.


특정 수의 경로 구성 요소를 제거하려면와 cut함께 사용해야합니다 -d'/'. 예를 들면 다음과 path=/home/dude/some/deepish/dir같습니다.

처음 두 구성 요소를 제거하려면 :

# (Add 2 to the number of components to remove to get the value to pass to -f)
$ echo $path | cut -d'/' -f4-
some/deepish/dir

처음 두 구성 요소를 유지하려면 :

$ echo $path | cut -d'/' -f-3
/home/dude

마지막 두 구성 요소를 제거하려면 ( rev문자열 반전) :

$ echo $path | rev | cut -d'/' -f4- | rev
/home/dude/some

마지막 세 가지 구성 요소를 유지하려면 :

$ echo $path | rev | cut -d'/' -f-3 | rev
some/deepish/dir

또는 특정 구성 요소 전에 모든 것을 제거하려면 다음과 같이 sed작동합니다.

$ echo $path | sed 's/.*\(some\)/\1/g'
some/deepish/dir

또는 특정 구성 요소 뒤에 :

$ echo $path | sed 's/\(dude\).*/\1/g'
/home/dude

지정하는 구성 요소를 유지하지 않으려는 경우 훨씬 더 쉽습니다.

$ echo $path | sed 's/some.*//g'
/home/dude/

일관성을 유지하려면 후행 슬래시도 일치시킬 수 있습니다.

$ echo $path | sed 's/\/some.*//g'
/home/dude

물론 여러 슬래시를 일치시키는 경우 sed구분 기호를 전환해야합니다 .

$ echo $path | sed 's!/some.*!!g'
/home/dude

이 예제는 모두 절대 경로를 사용하므로 상대 경로와 함께 작동하도록하려면 주위를 둘러보아야합니다.


제거 할 부분을 하드 코딩하지 않으려면 :

$ s='/path/to/file/drive/file/path/'
$ echo ${s#$(dirname "$(dirname "$s")")/}
file/path/

sed로이를 수행하는 한 가지 방법은

echo /path/to/file/drive/file/path/ | sed 's:^/path/to/file/drive/::'

${path#/path/to/file/drive/}악의적 인 오토가 제안한대로 사용 하는 것이 확실히 전형적인 / 최선의 방법이지만 sed 제안이 많기 때문에 고정 된 문자열로 작업하는 경우 sed가 과잉임을 지적하는 것이 좋습니다. 다음을 수행 할 수도 있습니다.

echo $PATH | cut -b 21-

처음 20자를 버립니다. 마찬가지로 ${PATH:20}bash 또는 $PATH[20,-1]zsh에서 사용할 수 있습니다 .


If you want to remove the first N parts of the path, you could of course use N calls to dirname, as in glenn's answer, but it's probably easier to use globbing:

path=/path/to/file/drive/file/path/
echo "${path#*/*/*/*/*/}"   #  file/path/

Specifically, ${path#*/*/*/*/*/} means "return $path minus the shortest prefix that contains 5 slashes".


Pure bash, without hard coding the answer

basenames()
{
  local d="${2}"
  for ((x=0; x<"${1}"; x++)); do
    d="${d%/*}"
  done
  echo "${2#"${d}"/}"
}
  • Argument 1 - How many levels do you want to keep (2 in the original question)
  • Argument 2 - The full path

ReferenceURL : https://stackoverflow.com/questions/10986794/remove-part-of-path-on-unix

반응형