DNF 및 YUM 명령에서 개행을 제거하는 방법은 무엇입니까?

DNF 및 YUM 명령에서 개행을 제거하는 방법은 무엇입니까?

rpm 기반 Linux 배포판(RHEL/Red Hat, Fedora, CentOS 등)에서 사용하는 경우 dnf유틸리티 yum는 사용자가 더 쉽게 읽을 수 있도록 자동으로 줄을 바꿉니다. 이는 파이프를 통한 데이터 처리를 매우 짜증나게 만들기 때문에 문제가 됩니다.

예를 들어:

$ dnf search jenkins-ssh-credentials-plugin-javadoc
Last metadata expiration check: 6 days, 15:30:08 ago on Thu Sep  1 21:09:10 2016.
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc =============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin
$ dnf search jenkins-ssh-credentials-plugin-javadoc | grep ssh
====== N/S Matched: jenkins-ssh-credentials-plugin-javadoc =======
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for
                                              : jenkins-ssh-credentials-plugin

DNF의 출력이 나오면 grep일반적으로 사용자에게 표시하는 것과 완전히 다른 방식으로 데이터를 래핑하기로 결정한다는 것을 알 수 있습니다.

이 동작과 관련하여 몇 가지 질문이 제기되었습니다(#584525,#986740CLOSED NOTABUG) 그리고 "Yum은 파이프라인에 적합하지 않거나 적합하지 않은 텍스트 기반 대화형 사용자 인터페이스"이기 때문에 질문은 항상 종료되었습니다. Red Hat 개발자의 솔루션은 "작업에 다른 도구를 사용"하는 것입니다.

repoquery특히 제공된 방법( 예: 설치)이 제대로 작동하지 않는 경우에는 이렇게 해야 하는 것이 불합리해 보입니다.존재하다dnf이 데이터의 출력을 구문 분석하려면 유틸리티 내에서 더 많은 패키지를 설치해야 합니다.

이상적으로는 사용자가 파이프라인에서 데이터를 사용할 수 있습니다. 대신, 데이터를 사용 가능하게 만드는 데 사용할 수 있는 간단한 한 줄짜리 코드가 있으면 좋을 것입니다.

답변1

sed이름별로 쓰여진 "예제" 명령/주문의 훌륭한 목록이 있습니다 sed1line.txt(http://sed.sourceforge.net/sed1line.txt). 이 상황에 도움이 되는 좋은 예가 이 문서에 있습니다.

# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'

dnf/ 출력의 경우, yum개행 문자는 하나 이상의 공백 인스턴스로 시작하고 그 뒤에 콜론(:), 그리고 더 많은 공백이 뒤따른다는 것을 알고 있습니다. 이 지식을 사용하여 sed 예제를 수정하여 이를 설명하고 다음 줄을 추가할 수 있습니다.

sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D'

이 경우 우리는 결정을 내려야 합니다. +"확장된" 정규식 세트의 일부 로서 -r해당 기호를 사용하기 위해 추가해야 하거나 해당 기호를 해당 위치(0개 이상의 공백과 일치)에 사용하도록 +대체 해야 합니다. *둘 다 괜찮습니다. 위의 예는 현명하게 말하면 정확합니다.

결과는 다음과 같습니다.

$ dnf search jenkins-ssh-credentials-plugin-javadoc | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D'  | grep ssh
============= N/S Matched: jenkins-ssh-credentials-plugin-javadoc ==============
jenkins-ssh-credentials-plugin-javadoc.noarch : Javadoc for jenkins-ssh-credentials-plugin

보시다시피 이제 grep예상대로 작동합니다. 또한 이를 통해 출력 형식을 보다 창의적으로 지정할 수 있으므로 패키지 목록을 보다 쉽게 ​​스캔할 수 있습니다.

$ dnf search ssh | sed -r -e :a -e '$!N;s/\n[[:space:]]+://;ta' -e 'P;D' | sort  | awk -F: '!($1~/^====/) {printf "%-40s : %s\n", $1, substr($0, index($0, $2))}'
ansible.noarch                           :  SSH-based configuration management, deployment, and task execution system
apache-sshd-javadoc.noarch               :  API documentation for apache-sshd
apache-sshd.noarch                       :  Apache SSHD
autossh.x86_64                           :  Utility to autorestart SSH tunnels
bareftp.x86_64                           :  File transfer client supporting the FTP, FTP over SSL/TLS (FTPS) and SSH
belier.noarch                            :  Generates scripts allowing you to chain many ssh connections
btrfs-sxbackup.noarch                    :  Incremental btrfs snapshot backups with push/pull support via SSH
...
trilead-ssh2.noarch                      :  SSH-2 protocol implementation in pure Java
WebShell.noarch                          :  SSL server for web-based SSH access from browsers and mobile devices
x11-ssh-askpass.x86_64                   :  A passphrase dialog for X and not only for OpenSSH

답변2

yum그리고dnf진행 메시지를 쓰려면 캐리지 리턴 문자를 사용하여 새 줄을 바꿉니다. 이 메시지는.grep줄에 포함된 제어 문자가 없다고 가정하면 이를 위해 설계되지 않았습니다.grep터미널에 대해 몇 가지 가정을 하지만 그건다른 이야기.

sed 스크립트를 사용하여 중복 인쇄된 줄을 "최종" 줄로 필터링했습니다(중복 인쇄된 부분을 모두 제거). 예제에서는script2log.sed,

# $Id: script2log.sed,v 1.3 2015/02/04 23:50:12 tom Exp $
#
# Trim ordinary ANSI sequences, then OSC sequences, then backspace
# sequences, then trailing CR's and finally overstruck sections of
# lines.
#
# There are still several interesting cases which cannot be handled
# with a script of this sort.  For example:
#       CSI K (clear line)
#       cursor movement within the line
s/␛[[][<=>?]\{0,1\}[;0-9]*[@-~]//g
s/␛[]][^␛]*␇//g
s/␛[]][^␛]*␛\\//g
:loop
s/[^␈]␈\(.\)/\1/g
t loop
s/␍␍*$//g
s/^.*␍//g
s/␛[^[]//g

이 작업은 먼저 한 줄에 있는 후행 캐리지 리턴 수를 제거한 다음 캐리지 리턴을 포함하는 줄 부분을 제거하는 두 명령을 사용하여 수행됩니다. 남은 것은 작성할 줄의 마지막 복사본입니다(원하는 내용).

s/␍␍*$//g
s/^.*␍//g

(예, 이는 스크립트의 캐리지 리턴입니다).

yum(or) 의 출력을 캡처할 때 dnf파이프로 연결하려고 시도하지 않습니다 grep(확실히 바람직하지 않은 결과가 생성됨). 대신에 저는 script출력을 캡처하고 후처리를 사용 했습니다 sed. 예를 들면 다음과 같습니다.

script -c "yum upgrade"
sed -f script2log.sed typescript >upgrade.log

관련 정보