코드를 복제하지 않고 특정 패턴을 필터링하고 인쇄하는 방법이 있습니까?

코드를 복제하지 않고 특정 패턴을 필터링하고 인쇄하는 방법이 있습니까?

소프트웨어를 설치 하는 데 pacman가끔 다음 형식의 오류가 발생합니다.

package-name: /some/package/file exists in filesystem

과거 어느 시점에 설치를 망쳤거나, 현명하지 않게 수동으로 무언가를 설치하려고 시도한 경우에 이런 일이 자주 발생합니다.

이 문제를 해결하려면 충돌하는 모든 패키지의 이름을 파일에 넣는 것이 유용합니다. 다음 방법을 사용하여 이 작업을 수행할 수 있습니다.

# pacman -S package-name |
   grep '^package-name: [^ ]* exists in filesystem$' |
   sed 's/^package-name: \([^ ]*\) exists in filesystem$/\1/' >
   conflicting_files.txt

그러나 이를 위해서는 동일한 내용을 두 번 입력해야 합니다. 정규식을 반복하지 않고 동일한 작업을 수행할 수 있는 방법이 있습니까?

답변1

많은 방법. 예를 들어, sed단독으로 사용됩니다(여기에서는 GNU 도구를 사용하고 있다고 가정합니다 pacman).

pacman -S package-name |
   sed -En 's/^package-name: ([^ ]*) exists in filesystem$/\1/p' >
   conflicting_files.txt

또는 grep:

pacman -S package-name |
   grep -oP '^package-name: \K\S+' >
   conflicting_files.txt

줄 끝을 일치시켜야 하는 경우 @RomanPerekhrest를 사용하세요.제안.

또는 perl:

pacman -S package-name |
   perl -ne 's/^package-name: (\S*) exists in filesystem$/$1/ && print' >
   conflicting_files.txt

또는 perl:

pacman -S package-name |
    perl -lane 'print $F[1] if /^package-name:.*exists in filesystem$/' >
    conflicting_files.txt

또는 awk:

pacman -S package-name |
    awk '/^package-name:.*exists in filesystem$/{print $2}' > 
    conflicting_files.txt

답변2

GNU를 사용하면 grep파이프를 다음과 같이 줄일 수 있습니다.

pacman -S package-name | grep -Po '^package-name: \K[^[:space:]]+(?= exists in filesystem$)' > conflicting_files.txt

또는 일치 [^[:space:]]하도록 변경할 수 있습니다.\S공백이 아닌주문하다.

답변3

다른 옵션을 던집니다.

packman -S package-name |
  pcregrep -xo1 'package-name: (\S+) exists in filesystem'

처럼:

packman -S package-name |
  perl -lne 'print $1 if /^package-name: (\S+) exists in filesystem$/'

휴대용/POSIX 방식은 다음과 같습니다.

sed -n 's/^package-name: \([^ ]*\) exists in filesystem$/\1/p'

관련 정보