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オプションを使用すると、組み込み機能をすばやく拡張できます-Pprint

%パラメータ拡張フラグを使用して、パラメータ拡張中に拡張を促すこともできます。

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

関連情報