여러 줄 여러 문자열을 한 줄로

여러 줄 여러 문자열을 한 줄로

입력(여러 줄):

abc def ghi 123 345 456 
abc def def ghi 123 345 456
abc def def def ghi 123 345 456 

출력(한 줄에서 한 줄로 문자열/정규식 추출):

def 345
def def 345
def def def 345

첫 번째...

echo "abc 123" | grep -Po "\Kabc|\K123"

하지만 이렇게 하면 두 줄이 인쇄됩니다.

abc
123

두번째:

echo -ne "abc def bac 123\nabc def def bac 123\nabc def def def bac 123 123\n" | grep -Po "def|123" | paste -d ' ' - -

그러나 이는 다음을 보여줍니다.

def 123
def def
123 def
def def
123 123

제 생각에는:

def 123
def def 123
def def def 123 123

\n을 제거하기 위해 tr을 사용할 수 없습니다. def 또는 345는 한 줄에서 여러 번 발견될 수 있으며 다른 모든 줄을 제거하는 \n은 의미가 없습니다. 열 구분 기호를 사용할 수 없습니다.

답변1

그리고perl

$ cat ip.txt
abc def ghi 123 345 456 
abc def def ghi 123 345 456
abc def def def ghi 123 345 456 1234

$ perl -lane 'print join " ", grep { /def|123/ } @F' ip.txt
def 123
def def 123
def def def 123 1234

$ perl -lane 'print join " ", grep { $_ eq "def" || $_ eq "123" } @F' ip.txt
def 123
def def 123
def def def 123
  • -lane여기서는 -l입력 줄에서 줄 바꿈을 제거하고 print사용할 때 다시 추가하고, -a입력 줄을 공백으로 자동으로 분할하고 결과를 @F배열에 저장하고, -n입력 줄을 반복하지만 처리 후 줄을 자동으로 인쇄하지 않고 -e명령에서 허용합니다 . Perl 스크립트 라인 제공
  • grep { /def|123/ } @F또는 @F를 포함하는 경우 배열의 모든 요소를 ​​필터링합니다 .def123
    • 정규식 대신 문자열 일치를 원하면 다음을 사용할 수 있습니다.grep { $_ eq "def" || $_ eq "123" } @F
  • print join " "grep공백을 구분 기호로 사용하여 출력에서 ​​얻은 요소를 인쇄합니다.

답변2

ex다음과 함께 사용 awk:

$ cat test.txt
abc def ghi 123 345 456 
abc def def ghi 123 345 456
abc def def def ghi 123 345 456
$ printf '%s\n' 'g/^/.!awk -v ORS=" " -v RS=" " "/^(def|345)$/"' %p | ex test.txt
def 345 
def def 345 
def def def 345 
$ 

그 기능은 다음과 같습니다:

  1. ex수정, 인쇄 및/또는 저장할 수 있는 버퍼(in)로 파일을 읽습니다 .
  2. awk스크립트를 통해 버퍼의 각 라인을 (개별적으로) 필터링합니다.
  3. 버퍼의 전체 내용을 인쇄합니다( 를 사용하여 %p).

위 명령은 결과를 파일에 다시 저장하지 않습니다. 이렇게 하려면 %p으로 바꾸면 됩니다 x.


더 자세한 설명:

ex스크립트 가능한 파일 편집기입니다. 파일 이름( test.txt)을 인수로 받아들이고 표준 입력에서 편집 명령을 가져옵니다.

여기서는 사용된 편집 명령을 제공합니다 printf. 첫 번째 매개변수 는 나머지 매개변수가 출력되는 방식을 제어하는 printf​​형식 문자열(이 경우 )입니다 . 모든 매개변수는 문자열이고 각 매개변수 뒤에 개행 문자가 인쇄되어야 한다고 말합니다. (작은 따옴표는 쉘이 백슬래시를 해석하는 것을 피하기 위해 존재합니다. 우리는 쉘이 아닌 백슬래시를 얻고 싶습니다.)'%s\n'printfprintf

ex을 사용하여 두 개의 매개변수를 보냅니다 printf. 여기 그들이 온다:

g/^/.!awk -v ORS=" " -v RS=" " "/^(def|345)$/"
%p

그 중 두 번째가 가장 간단합니다. %주소 범위입니다. 이는 "전체 버퍼"를 의미합니다. p인쇄 명령입니다. 따라서 이는 "전체 버퍼 인쇄"를 의미합니다.

첫 번째는 약간의 분해가 필요합니다.

g/.../"전역" 명령입니다. 전체 버퍼에서 주어진 패턴(이 경우 ^"줄의 시작"을 의미하는 정규식)과 일치하는 줄을 검색하고 ex해당 줄마다 다음 편집 명령을 실행합니다. 각 줄에는 줄 시작이 있으므로 모든 줄이 일치하므로 ^각 줄에서 다음 명령을 별도로 실행하는 효과가 있습니다.

그런 다음 ."(버퍼의) 현재 라인"을 의미하는 주소가 있습니다. 명령어 뒤에 나오므로 g버퍼의 각 라인을 차례로 참조한다.

!쉘 명령을 실행하는 데 사용됩니다. 주소가 앞에 붙으면(이 경우 .), 주어진 줄 범위(또는 단일 줄)가 주어진 쉘 명령에 제공됩니다.표준 입력명령의 결과(표준 출력)는 해당 라인의 버퍼에 배치됩니다.

즉, .!shell-command-herein은 ex일부 외부 명령을 통해 버퍼의 현재 라인을 필터링하는 것을 의미합니다.

우리는 이미 이 명령 설정이 명령으로 버퍼의 각 행을 (개별적으로) 필터링하는 방법을 다루었습니다. awk이제 명령을 분석해 보겠습니다 awk.

awk -v ORS=" " -v RS=" " "/^(def|345)$/"

awk이 플래그를 사용하여 변수를 정의할 수 있습니다 -v. 따라서 처음 몇 개의 매개변수 는 ORSRS변수를 단일 공백 ​​문자로 설정합니다.

RSin은 awk"레코드 구분 기호"입니다. 기본적으로 해당 값은 개행 문자입니다. 설정된 문자는 awk읽을 때 레코드(일반적으로 줄)를 구분하는 데 사용됩니다.

마찬가지로, ORS출력 레코드 구분자는 awk출력을 인쇄할 때 레코드(일반적으로 줄)를 구분하는 데 사용되는 항목을 제어합니다.

각 단어를 공백 문자로 설정하면 줄의 각 단어를 단일 레코드로 쉽게 작업할 수 있습니다.

다음 부분은 실제 awk명령입니다. ( awk자체 스크립팅 언어입니다.) awk명령 블록은 조건과 동작으로 구성됩니다. 여기서 조건은 /.../정규식 일치입니다. 즉, 조건은 주어진 정규식과 일치하는 모든 레코드(이 경우 단어)에 적용됩니다. 정규식 부분은 ^(문자열의 시작), $(문자열의 끝)이며, 두 가지 가능한 패턴은 괄호 안에 그룹화되고 |(파이프라인)으로 구분되어 이러한 패턴 중 어느 것이든 허용 가능함을 나타냅니다.

조건 뒤에는 액션이 ​​없으므로(액션은 중괄호 안에 표시됨 awk) awk의 기본 액션 "print"는 조건과 일치하는 레코드에 적용됩니다. (이것은 해당 줄에 대해 일치하는 각 레코드(단어)가 인쇄된 다음 해당 출력이 읽혀지고 awk처음 입력된 ex버퍼의 줄 위치에 배치된다는 것을 의미합니다.)exawk

이 솔루션은 모든 패턴이 완전한 단어와 일치한다는 단순화된 가정을 합니다. 즉, 다음 패턴 중 어느 것과도 일치하지 않으려고 합니다.포함하다공백. 이는 질문에 제공한 입력 예시와 일치합니다.

답변3

awk원하는 필드만 사용하고 유지할 수 있습니다 .

echo -e "abc def bac 123\nabc def def bac 123\nabc def def def bac 123 123" \
  | awk -v var1="def" -v var2="123" '{
  i=0
  for (j=1; j<=NF; j++){
    if ($j==var1 || $j==var2){ $++i=$j }
    if (i!=j){ $j="" }
  }
  print
}'

이는 for 루프의 필드를 반복하고 def또는 123다음 필드에 다시 할당합니다 $++i=$j(인덱스 0에서 시작하므로 첫 번째 필드는 1이고 다음 필드는 2입니다...). 인덱스가 비어 있으면 재설정됩니다. $j빈 문자열( $j="") 에 대한 현재 필드 i는 순환 인덱스가 아닙니다 j.

산출:

def 123
def def 123
def def def 123 123

관련 정보