문자열과 일치하는 프로그램에서 여러 줄의 출력을 가져와서 일치하는 이전 줄을 모두 반환해야 합니다.
프로그램 출력의 예:
$ jack_lsp -p
firewire_pcm:analog-1_out
properties: input,physical,terminal,
firewire_pcm:analog-2_out
properties: input,physical,terminal,
firewire_pcm:analog-1_in
properties: output,physical,terminal,
firewire_pcm:analog-2_in
properties: output,physical,terminal,
$
일치시키고 "입력"이라고 말하고 일치하는 모든 이전 행을 반환해야 합니다. 따라서 이 예에서 예상되는 출력은 다음과 같습니다.
firewire_pcm:analog-1_out
firewire_pcm:analog-2_out
이것이 내가 가지고 있는 것이지만 첫 번째 일치 항목만 반환합니다.
$ jack_lsp -p | grep -B1 input | head -1
firewire_pcm:analog-1_out
$
내가 뭘 잘못했나요?
답변1
이것은 당신이 시도하는 명령입니다:
jack_lsp -p | grep -B1 input | head -1
문제는 head -1
첫 번째 행이 반환된다는 것입니다.모두데이터 스트림이 파이프로 연결됩니다.
다음 awk
명령을 사용해 보십시오:
jack_lsp -p | awk '/input/{print previous_line}{previous_line=$0}'
"input"이라는 문자열이 포함된 각 줄 앞에 해당 줄을 인쇄합니다. 예제 데이터의 결과는 다음과 같습니다.
user@host:~$ cat <<HEREDOC | awk '/input/{print previous_line}{previous_line=$0}'
firewire_pcm:analog-1_out
properties: input,physical,terminal,
firewire_pcm:analog-2_out
properties: input,physical,terminal,
firewire_pcm:analog-1_in
properties: output,physical,terminal,
firewire_pcm:analog-2_in
properties: output,physical,terminal,
HEREDOC
firewire_pcm:analog-1_out
firewire_pcm:analog-2_out
이 방법에 대한 자세한 내용은 awk
다음 게시물을 참조하세요.
다음을 사용하여 동일한 작업을 수행할 수 있습니다 sed
.
<!-- language: bash -->
jack_lsp -p |sed -n '/input/{x;p;d;}; x'
이 방법에 대한 자세한 내용은 sed
다음 게시물을 참조하세요.
특별한 경우에는 일치하는 문자열(예: "input")이 이전 행에 나타나지 않는 것처럼 보이므로 다음을 사용하여 해당 행을 필터링할 수도 있습니다 grep
.
jack_lsp -p | grep -B1 'input' | grep -v 'input
awk
grep
결과가 간단하지는 않지만 일부 쉘 스크립트를 보완하여 위 방법과 동일한 결과를 얻을 수도 있습니다.
jack_lsp -p | (
unset previous_line;
while read line; do
if grep -q input <<< "${line}" && [[ -n "${previous_line}" ]]; then
echo "${previous_line}";
fi;
previous_line="${line}";
done
)
답변2
gnu-grep(모든 플랫폼에서 사용 가능하며 대부분의 플랫폼에 기본적으로 설치됨)을 사용하면 다음을 수행할 수 있습니다.
jack_lsp -p | grep -zPo '.*\n(?=.*input)'
어디
-z
null로 구분된 "줄"을 나타냅니다(실제로 전체 파일을 차지하게 됩니다) - 여러 줄 모드 사용-P
Perl과 유사한 정규식 방언 - 미리보기 기능 포함'.*\n(?=.*input)'
"input"을 포함하는 다른 줄이 기대되는 줄
답변3
ex
간단하게 유지하고 역방향 주소 지정 기능 을 사용하는 것은 어떨까요 ?
printf '%s\n' 'g/input/-p' | ex file.txt
파일 대신 파이프에서 실행하는 것이 조금 더 까다로워 보이지만 동일하게 작동합니다.
jack_lsp -p | ex -s /dev/stdin -c $'g/input/-p\nq'
답변4
이 스니펫:
# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
pl " Input data file $FILE:"
head $FILE
pl " Expected output:"
cat $E
pl " Results:"
rm -f f1
ed --silent $FILE > f1 <<EOF
g/input/.-1p
q
EOF
head f1
생산하다:
-----
Input data file data1:
firewire_pcm:analog-1_out
properties: input,physical,terminal,
firewire_pcm:analog-2_out
properties: input,physical,terminal,
firewire_pcm:analog-1_in
properties: output,physical,terminal,
firewire_pcm:analog-2_in
properties: output,physical,terminal,
-----
Expected output:
firewire_pcm:analog-1_out
firewire_pcm:analog-2_out
-----
Results:
firewire_pcm:analog-1_out
firewire_pcm:analog-2_out
ed 명령은 간단합니다. 1) "input"과 일치하는 줄을 찾습니다. 2) 이전 줄을 인쇄합니다.
다음 시스템에서 실행됩니다.
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.9 (jessie)
ed GNU Ed 1.10
행운을 빕니다... 건배, drl