쉘 명령을 사용하여 텍스트 파일의 첫 번째 열과 마지막 열만 표시하는 방법은 무엇입니까?


30

sed 명령을 사용하여 텍스트 파일의 첫 번째 열과 마지막 열만 표시하는 방법을 알아내는 데 도움이 필요합니다. 1 열에 대해 지금까지 가지고있는 내용은 다음과 같습니다.

cat logfile | sed 's/\|/ /'|awk '{print $1}'

마지막 열을 보여주기위한 나의 미약 한 시도는 다음과 같습니다.

cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'

그러나 이것은 첫 번째 열과 마지막 열을 가져 와서 하나의 목록으로 병합합니다. sed 및 awk 명령으로 첫 번째 열과 마지막 열을 명확하게 인쇄하는 방법이 있습니까?

샘플 입력 :

foo|dog|cat|mouse|lion|ox|tiger|bar

5
샘플 입력을 제공하십시오.
jasonwryan

답변:


51

거의 다 왔어. 두 열 참조를 서로 옆에 두십시오.

cat logfile | sed 's/|/ /' | awk '{print $1, $8}'

또한 cat여기 에는 필요하지 않습니다 .

sed 's/|/ /' logfile | awk '{print $1, $8}'

또한 awk열 구분 기호는 |공백 대신이므로 구분할 필요가 없습니다 sed.

awk -F '|' '{print $1, $8}' logfile

Caleb의 제안 에 따라 , 마지막 필드를 여전히 출력하는 솔루션을 원한다면 정확히 8 개가 없더라도 사용할 수 있습니다 .$NF

awk -F '|' '{print $1, $NF}' logfile

또한 |공백을 사용하지 않고 출력에 구분 기호 를 유지 하려면 출력 필드 구분 기호를 지정할 수 있습니다. 불행히도 -F플래그를 사용하는 것보다 조금 더 서투른 일이지만 여기에 세 가지 접근 방식이 있습니다.

  • awkBEGIN 블록 에서 입력 및 출력 필드 구분 기호 자체를 할당 할 수 있습니다 .

    awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
  • awk명령 행에서 호출 할 때 -v플래그 를 통해 이러한 변수를 지정할 수 있습니다 .

    awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
  • 또는 간단히 :

    awk -F '|' '{print $1 "|" $8}' logfile

4
이 문제를 단순화 할 수있는 방법을 잘 정리했습니다. |문자열 연결을위한 기본 공간 대신 ​​출력 구분 기호 로 사용하는 방법에 대한 메모를 추가 할 수 있습니다 . 또한 마지막 열을 얻기 위해 $NF하드 코딩 대신 사용 하는 방법을 설명 할 수 있습니다 $8.
Caleb

12

첫 번째에서 마지막 |으로 바꾸십시오 |(또는 원하는 경우 공백).

sed 's/|.*|/|/'

더 없다하더라도 것을 참고 sed구현 |(만큼 특별한 확장 된 정규 표현식을 통해 사용할 수 없습니다 -E또는 -r일부 구현에) \|자체는 GNU 같은 일부에서 특별하다 sed. 따라서 캐릭터 와 일치 시키려면 탈출 하지 않아야 합니다.||

공백으로 바꾸고 입력에 이미 하나만있는 줄이 포함되어 있으면 해당 줄과 일치하지 않는 |것으로 간주해야 |.*|합니다. 그럴 수 있습니다 :

sed 's/|\(.*|\)\{0,1\}/ /'

(그 .*|부분은 선택 사항입니다) 또는 :

sed 's/|.*|/ /;s/|/ /'

또는:

sed 's/\([^|]*\).*|/\1 /'

입력의 필드 수에 관계없이 첫 번째와 여덟 번째 필드를 원한다면 다음과 같습니다.

cut -d'|' -f1,8


(모든 특히 (입력 형태의 유효한 텍스트를 가정하고 모든 POSIX 호환 유틸리티를 사용하여 작업 할의 sed사람 것입니다 일반적으로하지 작업 입력은 예를 들어 같은 현재의 지역에서 유효한 문자를 형성하지 않는 바이트의 바이트 순서가있는 경우 printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'에을 UTF-8 로케일)).


11

awk어쨌든 사용 하고 있습니다 :

awk '{ print $1, $NF }' file

2
입력 필드 구분 기호를 지정하지 않아도 됩니까 (이 경우 |공간 이 아닌 것 같습니다 ) -F\|? 또한 출력에 동일한 구분자를 사용하려면 어떻게해야합니까?
Caleb

@Caleb 아마 : 나는 무엇을 확인하기 위해 OP를 기다리고 있었다 정확히 ... 오히려 작동하지 않는 사례를 기반으로 생각하는 것보다, 입력이처럼 보였다
jasonwryan

1
입력에 2 개 이상의 필드가 있다고 가정합니다.
Stéphane Chazelas

@ StéphaneChazelas OP는 코드에 항상 8 개의 필드가 있다고 명시했습니다.
michaelb958-- 복원 주 모니카

3
@ michaelb958 나는 "명확하게"의 경우, 조금 :) 과장 생각
jasonwryan

4

자신이 어색하고 sed-less 인 경우 coreutils를 사용하여 동일한 결과를 얻을 수 있습니다.

paste <(           cut -d'|' -f1  file) \ 
      <(rev file | cut -d'|' -f1 | rev)

cut첫 번째 열에 관심이 있거나 delimeters가 고정되어있는 경우 (즉, 가변 수의 공간이 아님) awk / sed보다 더 깨끗하고 간결합니다.
Sridhar Sarnobat

2

로 구분 된 첫 번째 및 마지막 텍스트 필드를 얻으려고하는 것 같습니다 |.

로그 파일에 아래와 같은 텍스트가 있다고 가정합니다.

foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo

그리고 당신은 출력을 원합니다.

foo bar
bar foo

그렇다면 여기에 대한 명령 이옵니다.

GNU sed를 통해

sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file

예:

$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar

열은 파이프로 구분되지 않습니다 | 그러나 그들은 열에 있으며 sed를 사용하고 싶지만 명령에서했던 것처럼 awk 명령을 사용하지는 않습니다. sed -r 's ~ ^ ([^ |] *). * \ | (. *) $ ~ \ 1 \ 2 ~ '파일
user70573 2016 년

"열은 파이프로 구분되지 않고 열에 있습니다."열이 공백으로 구분되어 있습니까?
Avinash Raj

샘플 입력과 출력이 더 좋습니다.
Avinash Raj

1

sed어쨌든 그렇게해야하지만 아마도 아무도이 책을 쓰지 않았을 것입니다.

while IFS=\| read col1 cols
do  printf %10s%-s\\n "$col1 |" " ${cols##*|}"
done <<\INPUT
foo|dog|cat|mouse|lion|ox|tiger|bar
INPUT

산출

     foo | bar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.