sed 명령을 사용하여 /home/user를 ~로 바꾸는 방법

sed 명령을 사용하여 /home/user를 ~로 바꾸는 방법

이것이 다음의 출력이라고 가정합니다 pwd.

/home/amarakon/.local/src/amarakon/scripts/src

이것을 어떻게 바꿀 수 있습니까?

~/.local/src/amarakon/scripts/src

나는 다음 명령을 시도했습니다.

pwd | sed 's|/home/.*|~|'

그러나 결과는 다음과 같습니다.

~

답변1

사용하는 경우 zsh다음을 사용할 수 있습니다.

print -P '%~'

현재 작업 디렉토리를 얻으려면 홈 디렉토리를 로 바꾸십시오 ~. 홈 디렉토리이고 이전에 확장된 경우에도 /home/directory/of/otheruser로 대체됩니다.~otheruser/home/directory/of/otheruserotheruser~otheruser

일반적으로 현재 작업 디렉터리를 얻으려면 %~your 를 입력합니다. $PROMPT옵션을 사용하면 내장된 기능을 빠르게 확장할 수 있습니다 -P.print

%매개변수 확장 플래그를 사용하여 매개변수 확장 중에 확장을 프롬프트할 수도 있습니다 .

printf '%s\n' ${(%):-%~}

~이 대체는 매개변수 확장 플래그를 사용하여 활성화할 수도 있으므로 다음을 D수행할 수도 있습니다.

printf '%s\n' ${(D)PWD}

수동으로 수행할 수도 있습니다.

set -o extendedglob
printf '%s\n' ${PWD/#%(#b)$HOME(|\/*)/\~$match[1]}

$HOME그러나 심볼릭 링크 또는 .경로 구성 요소가 있거나 $PWD심볼릭 링크 구성 요소가 있는 경우 다른 패밀리 표현을 포함하는 변수로 끝나기 때문에 이것이 작동하지 않을 수 있다는 점에 유의하십시오 .

sed임의의 값에 대해 이 작업을 수행하려는 경우 이는 문제가 될 수 있습니다 $HOME. 당신은해야합니다/먼저 이스케이프 및 정규식 연산자( .정규식 연산자로, 사용자 이름에서 일반적임) Cdir 경로가 텍스트라고 보장되지 않으므로 로케일에서 이 작업을 수행합니다. 모든 줄을 $PWD패턴 공간의 시작 부분에서만 로드하고 /주제의 교체 또는 끝을 따를 때만 로드합니다.

escaped_HOME=$(printf '%s\n' ~ | LC_ALL=C sed '
  :1
  $!{
    N
    b1
  }
  s:[][\\/.^$*]:\\&:g
  s/\n/\\n/g'
)
pwd | LC_ALL=C sed '
  :1
  $!{
    N
    b1
  }
  s/^'"$escaped_HOME"'\(\(\/.*\)\{0,1\}\)$/~\1/'

최고의 도구는 아닙니다. 그리고 perl:

perl -MCwd -le 'print getcwd =~ s|^\Q$ENV{HOME}\E(?![^/])|~|r'

그렇다면 일부 시스템 사용자의 경우처럼 $HOME" which "를 "or"로 바꾸지 않는 것이 좋을 수 있습니다 . 수동식은 교체될 예정 이지만 제 생각에는 허용되지 않습니다 ./%~/~/dir~/dir/~/dir~/dir

답변2

다른 사람들이 말했듯이 일치 항목을 바꾸면 일치 항목이 문자열의 맨 끝 부분으로 이동하므로 표시된 예에서 전체 문자열이 /home/.*대체됩니다 .~.*

이 변수는 PWD또한 우리가 사용할 수 있는 현재 디렉터리에 대한 경로를 보유합니다.많은이 값에 대한 더 저렴한 매개변수 대체:

[[ "$PWD/" == "${HOME%/}/"* ]] && printf '~%s\n' "${PWD#"${HOME%/}"}"

처음에 $PWD포함되어 있는지 테스트 하고, 포함되어 있으면 으로 교체된 부분을 인쇄합니다 . 이는 값비싸고 상대적으로 느리게 실행되는 외부 유틸리티가 필요하지 않기 때문에 훨씬 빠릅니다.$HOME$PWD~

휴대성이 향상되었습니다.

case $PWD/ in ("${HOME%/}/"*) printf '~%s\n' "${PWD#"${HOME%/}"}"; esac

답변3

.모든 문자와 일치하므로 후행 슬래시 및 경로 부분을 포함하여 줄에 남아 있는 모든 것과 일치합니다.

기본적으로 패턴의 해당 부분을 슬래시가 아닌 일련의 항목으로 제한하려고 하므로 슬래시가 발생하면(슬래시가 발생하면) 교체가 중지됩니다.

pwd | sed 's|/home/[^/]*|~|'

루트 폴더 외부에 이름이 지정된 하위 폴더가 있는 경우 해당 폴더가 '/home'시작 부분에 있도록 요구하는 것을 고려할 수 있습니다.home

pwd | sed 's|^/home/[^/]*|~|'

이것은 pwd 출력에 작동하지만 $HOME을 긴 문자열에서 ~로 바꾸면 첫 번째 방법을 유지할 수 있습니다.

답변4

나는 이것이 오래된 질문이라는 것을 알고 있지만 문자열 연산자를 사용하여 이를 달성할 수 있습니다.

$ pwd
/home/kali/Documents
$ [ -z "${PWD%%$HOME*}" ] && echo ${PWD/$HOME/'~'} || echo $PWD
~/Documents

$ pwd
/etc/systemd/network
$ [ -z "${PWD%%$HOME*}" ] && echo ${PWD/$HOME/'~'} || echo $PWD
/etc/systemd/network

$ pwd
/tmp/home/kali/Documents
$ [ -z "${PWD%%$HOME*}" ] && echo ${PWD/$HOME/'~'} || echo $PWD
/tmp/home/kali/Documents

이제 구체적으로 질문하셨습니다 sed. 이것이 최고의 도구이거나 필요하다고 생각하지 않지만 다음을 수행합니다.

$ pwd | sed "s|^$HOME|~|"
~/Documents

관련 정보