마지막 / 이후의 모든 문자 자르기


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이미 수행했습니다.
Michael Hampton

질문에 대한 편집 # 5가 정확하다고 생각하지 않습니다. "잘라 내기"라는 단어를 사용하면 모호 할 수 있습니다. 무언가를 자르면 그 부분을 버리는가, 아니면 그 부분 만 유지 하는가? 그러나 이전의 "/ 이전에있는 것을 생략하는"문구는 분명했습니다. 이것은 반대쪽으로 변경되었습니다.
egmont

@egmont "cut"이라는 단어 자체는 다음과 같이 원본에서 그대로 사용 /되었습니다. "마지막 '/'뒤에있는 모든 문자를 어떻게 잘라 내야합니까?" 그것은 의미를 합리적으로 유지하는 문구의 변화입니다. 어쨌든, 나는 "무엇을 생략한다"라는 부분이 모호하다고 느꼈다 /. 예, 어쨌든 명확하게합니다.
muru

@muru 나는 ​​편집이 아닌 예제를 추가 한 편집에 대해 이야기하고 있습니다.
egmont

답변:


15

"절단 부분"을 얻으려면

yyy
yyyyy

당신이 사용할 수있는

sed 's|.*/||' 

예.

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

산출

yyy
yyyyy

(참고 : 이것은 sed에서 / 이외의 구분 기호를 사용하는 기능을 사용합니다 (이 경우 | s 명령에서 |)).


문자열의 시작을 원한다면 :

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
사용하기 위해 제안 된 수정 사항을 제출했습니다. | 대신에 /. 마음에 들지 않으면 "거부 및 편집"하고 "begginning"을 "beginning"으로 변경하십시오. (거부 + 편집은 robo 승인자에 의해 승인되지 않으므로 거부됩니다. 또는 승인 된 후 변경 사항을 승인하면 마음에 들지 않습니다.)
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의 질문에 적절한 솔루션을 사용 그래서 dirnamebasename관련된 것 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전체 줄 대신 일치하는 부분 만 표시하도록 지시 합니다.

패턴은 /[^/]*$리터럴 슬래시 일치 /A가 슬래시 제외한 모든 문자 뒤에 [^/]여러번 *라인의 끝까지를 $.


8

다른 사람들이 더 많은 "정상적인"답변을 게시했기 때문에 다음과 같은 어리석은 답변이 있습니다.

rev | cut -d/ -f1 | rev

rev각 행의 문자를 반전시킵니다 (예 : abcd/ef/g가 됨) g/fe/dcba. 그런 다음 cut첫 번째 세그먼트를 잘라냅니다. 마지막으로 다시 반전됩니다.


2
특히 쉘 배관 때문에이 답변의
비위생

합의-제정신이 아니라 나쁜 것!
Volker Siegel

3

를 사용하는 클래식 솔루션으로 awk, /입력 및 출력 모두에 대한 필드 구분 기호로 취급 하고 마지막 필드를 빈 문자열 (실제로 필드 수 NFvariable 의 "역 참조" )로 설정합니다.

$ 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--. 이런 식으로 당신은 printbla bla 를 소리 질러 .
fedorqui

3

질문이 수정되어 egmont의 답변에 추가 중 ...

-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이전 에 옵션을 보지 못했고 매뉴얼 페이지는 원형입니다. 보완은 보완을 의미합니다. 나는 그것을 커버하는 좋은 컷 튜토리얼 발견 yourownlinux.com/2015/05/... 그것은처럼 -v의를 grep. 일치하는 것을 제외한 모든 것을 줘.
Joe

2
-f2-에 대한 더 간단한 양식입니다 -f1 --complement.
egmont
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.