最後以降のすべての文字をカット/


14

最後の「/」の後のすべての文字をカットするにはどうすればよいですか?

このテキスト

xxxx/x/xx/xx/xxxx/x/yyyyy
xxx/xxxx/xxxxx/yyy

戻るはずです

xxxx/x/xx/xx/xxxx/x
xxx/xxxx/xxxxx

良い質問は、私はちょうど私たちが質問を同じように理解していなかったことに気づいた
Félicienの

3
コマンドbasenamedirnameこれをすでに行います。
マイケルハンプトン

質問の編集5は正しかったとは思いません。「カット」という単語を使用することは、あいまいかもしれません。何かを切った場合、その部分を捨てますか、それともそれを保持しますか?ただし、以前の「/の前にあるものを省略する」という表現はあいまいではありませんでした。これは反対に変更されました。
エモント2018年

@egmont「カット」という単語自体がオリジナルから引き継がれました:「最後の文字だけをカットする必要があります/」は「最後の「/」以降のすべての文字をどのようにカットしますか?」これは、IMOの意味を合理的に保つための表現の変更です。どちらかと言えば、「何を省略しているのか...」という部分があいまいだと感じました/。例では、とにかくそれを明確にします。
muru、2018年

@muru私はあなたの編集ではなく、例を追加した編集について話している。
エモント2018年

回答:


15

「カットパーツ」を手に入れたいなら

yyy
yyyyy

使用できます

sed 's|.*/||' 

例えば。

echo "xxx/xxxx/xxxxx/yyy" | sed 's|.*/||'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|.*\/||'

出力

yyy
yyyyy

(注:これは、sコマンドで/以外の区切り文字(この場合は|)を使用するsedの機能を使用しています)


文字列の先頭を取得したい場合:

xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x

使用できます

sed 's|\(.*\)/.*|\1|'

例えば。

echo "xxx/xxxx/xxxxx/yyy" | sed 's|\(.*\)/.*|\1|'
echo "xxxx/x/xx/xx/xxxx/x/yyyyy" | sed 's|\(.*\)/.*|\1|'

出力

xxx/xxxx/xxxxx
xxxx/x/xx/xx/xxxx/x

6
こんにちは、この場合、たとえばの#代わりに区切り文字を変更できます/。また、-r`\`の各特殊文字をエスケープしたくない場合は、このオプションを使用できますsed -r 's#(^.*)/.*$#\1#'
pa4080

1
使用する編集案を提出しました| の代わりに /。それが気に入らない場合は、「拒否して編集」し、「開始」を「開始」に変更することをお勧めします。(拒否+編集。この方法ではrobo-approversによって承認されません。または、変更が承認され、それが気に入らなかった場合は、ロールバックするだけです。)
Martin BonnerはMonica

18

あなたはカットしている場合はオフ文字列の端を、dirname法案に合うかもしれません。

$ dirname xxxx/x/xx/xx/xxxx/x/yyyyy
xxxx/x/xx/xx/xxxx/x
$ _

文字列の最後の部分を分離する場合は、を使用しますecho /$(basename "$str")

$ str=xxxx/x/xx/xx/xxxx/x/yyyyy
$ echo /$(basename "$str")
/yyyyy
$ _

3
正直なところ、OSにインストールされているユーティリティを使用するだけでなく、sed(またはawk、またはその他の同様の方法)に関する回答を提案または受け入れる理由は、私にはわかりません。
Auspex

@Auspex 広く知られているわけdirnamebasenameはないからだと思いますがsed、そうawkです。
Volker Siegel

@Auspex:dirnameとbasenameはstdinを操作しないため、機能しませんcat text | basename。OPの質問に対する適切な解決策を使用してdirnameおよびbasename伴うだろうxargsなど
ポッド

16

でのパラメータ拡張 bash

bashこの場合、パラメータ拡張をで使用できます。

  • ${parameter%word}どこword/*
  • ${parameter##word}どこword*/

例:

最後の部分を削除

$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf%/*}
xxx/xxxx/xxxxx

これについては、man bash以下で説明されています。

${parameter%word}
${parameter%%word}
      Remove matching suffix pattern.  The word is expanded to produce
      a pattern just as in pathname expansion.  If the pattern matches
      a  trailing portion of the expanded value of parameter, then the
      result of the expansion is the expanded value of parameter  with
      the  shortest  matching  pattern (the ``%'' case) or the longest
      matching pattern (the ``%%'' case) deleted.  If parameter  is  @
      or  *,  the  pattern  removal operation is applied to each posi‐
      tional parameter in turn, and the  expansion  is  the  resultant
      list.   If  parameter is an array variable subscripted with @ or
      *, the pattern removal operation is applied to  each  member  of
      the array in turn, and the expansion is the resultant list.

最後の部分を除いてすべて削除

$ asdf="xxx/xxxx/xxxxx/yyy"
$ echo ${asdf##*/}
yyy

このようにスラッシュを追加できます

$ echo /${asdf##*/}
/yyy

編集された質問に従って、特定のインスタンスで必要なものを正確に取得します。しかし、その質問はその後何人かの人々によって編集されており、あなたが今何を望んでいるかを知ることは容易ではありません。

これについては、man bash以下で説明されています。

${parameter#word}
${parameter##word}
      Remove matching prefix pattern.  The word is expanded to produce
      a pattern just as in pathname expansion.  If the pattern matches
      the  beginning of the value of parameter, then the result of the
      expansion is the expanded value of parameter with  the  shortest
      matching  pattern  (the ``#'' case) or the longest matching pat‐
      tern (the ``##'' case) deleted.  If parameter is  @  or  *,  the
      pattern  removal operation is applied to each positional parame‐
      ter in turn, and the expansion is the resultant list.  If param‐
      eter  is  an array variable subscripted with @ or *, the pattern
      removal operation is applied to each  member  of  the  array  in
      turn, and the expansion is the resultant list.

10

別の方法は、を使用grepして、行ごとの最後のスラッシュとそれに続くものだけを表示することです。

$ grep -o '/[^/]*$' example.txt
/yyy
/yyyyy

説明:

-ogrep行全体ではなく、行の一致する部分のみを表示するように指示します。

パターンは、行の終わりまで、スラッシュを除く/[^/]*$リテラルスラッシュと/それに続く任意の文字[^/]に何度でも*一致し$ます。


8

他の人がより「健全な」回答を投稿したという理由だけで、これはやや馬鹿げた回答です。

rev | cut -d/ -f1 | rev

rev各行の文字を逆にします。たとえば、にabcd/ef/gなりg/fe/dcbaます。次にcut、最初のセグメントを切り取ります。最後に、それは再び逆転しました。


2
この回答は正気ではないものの、特にシェルの配管が原因で、私はこの回答が好きです:)
頑張って

同意した-正気ではなく、ワル!
Volker Siegel

3

入力と出力の両方でフィールドセパレーターとしてawk扱い/、最後のフィールドを空の文字列に設定する従来のソリューション(フィールドNF変数の数の実際の「逆参照」):

$ echo "xxx/xxxx/xxxxx/yyy"|awk  'BEGIN{OFS=FS="/"};{$NF="";print $0}'
xxx/xxxx/xxxxx/

もっと短い、fedorquiがコメントで指摘したように:

$ echo "xxx/xxxx/xxxxx/yyy"|awk  'BEGIN{OFS=FS="/"};NF--'
xxx/xxxx/xxxxx/

そのバリエーションは、awkの実行環境にパスを入れることです。これにより、配管を節約できますが、awk部分がより冗長になります。

mypath="xxx/xxxx/xxxxx/yyy" awk  'BEGIN{OFS=FS="/"; sub(/\/([^\/]*)$/,"",ENVIRON["mypath"]);print(ENVIRON["mypath"]) };'

1
冗長すぎNF--ます。なぜですか?このようにして、あなたは何よりも大嫌いprintです。
fedorqui 2018

3

質問が編集されたため、エグモントの回答に追加しています...

-f1を使用して最初のフィールドを削除する場合は、-complementを使用します

echo "xxxx/x/xx/xx/xxxx/x/yyyyy"|rev|cut -d/ -f1 --complement|rev
xxxx/x/xx/xx/xxxx/x

echo "xxxx/x/xx/xx/xxxx/x/yyyyy"|rev|cut -d/ -f1|rev
yyyyy

また、スラッシュを含まない入力で何が起こるかについての質問は完全に明確ではありません。xxxx => xxxxまたはxxxx => なし


編集を提案することができます:askubuntu.com/posts/1010356/edit
muru

@muru OPは1担当者です。2kで編集権限が付与されていませんか?askubuntu.com/help/privileges/edit
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy誰でも編集を提案できます。
muru、

+1- --complement以前はオプションに気づかなかったため、manページは循環しています。補数は補数を意味します。yourownlinux.com/2015/05/でそれをカバーする素敵なカットチュートリアルを見つけましたのようなもの-vですgrep。一致したもの以外のすべてを私にくれ。
ジョー

2
-f2-はの単純な形式です-f1 --complement
エモント2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.