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

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 

댓글

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

답변

거의 완료되었습니다. 두 열 참조를 나란히 배치하기 만하면됩니다.

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

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

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

또한 열 구분 기호가 |

에 알릴 수 있습니다.

, 공백 대신 “sed도 필요하지 않습니다.

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

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

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

또한 원하는 경우 공백을 사용하는 대신 | 구분 기호를 유지하도록 출력하려면 출력 필드 구분 기호를 지정할 수 있습니다. 안타깝게도 -F 플래그를 사용하는 것보다 약간 어색하지만 여기에 세 가지 접근 방식이 있습니다.

  • 입력을 할당 할 수 있습니다. BEGIN 블록의 awk 자체에있는 출력 필드 구분 기호입니다.

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

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

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

댓글

  • 이 문제를 단순화 할 수있는 방법을 분석했습니다. 대신 |를 출력 구분자로 사용하는 방법에 대한 메모를 추가 할 수 있습니다. 문자열 연결을위한 기본 공간입니다. 마지막 열을 가져 오기 위해 $8를 하드 코딩하는 대신 $NF를 사용하도록 설명 할 수 있습니다.
  • 그 후에 파일을 업데이트하는 방법은 무엇입니까?
  • @pankajprasad 새 파일 재치에 쓰기 h > 그런 다음 이전 항목을 덮어 쓰거나 sponge를 사용합니다. 하지만 이것은 정말 새로운 질문입니다.
  • @Sparhawk 작동하지만 리밍 콘텐츠는 지워집니다. 어떻게 처리할까요?
  • @pankajprasad 새로운 질문이 필요합니다. 상단에있는 " 질문하기 "라고 표시된 큰 파란색 버튼을 클릭합니다.

답변

어쨌든 awk를 사용 중입니다.

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

댓글

  • 입력 필드 구분자를 지정할 필요가 없습니다 ' (이 경우에는 -F\| 또는 이와 유사한 공간이있는 |일까요? 또한 출력에 동일한 구분 기호를 사용하고 싶다면 어떻게해야합니까?
  • @Caleb 아마도 : OP가 입력이 정확하게 어떻게 생겼는지 확인하기를 기다리고있었습니다. 작동하지 않는 예제를 기반으로 추측 …
  • 입력에 2 개 이상의 필드가 포함되어 있다고 가정합니다.
  • @St é phaneChazelas OP는 코드에 항상 8 개의 필드가 있다고 명시했습니다.
  • @ michaelb958 " 명확하게 "는 사례를 과장하고 있습니다. 약간만 있습니다. 🙂

답변

처음부터 마지막으로 만 교체 | with | (또는 원하는 경우 공백) :

sed "s/|.*|/|/" 

|가 특수한 sed 구현은 없지만 ( 확장 일반 표현식은 -E 또는 ), \| 자체는 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/|.*|/|/")).

Answer

어색함과 sed-less를 발견하면 coreutils도 마찬가지입니다.

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

댓글

  • cut는 첫 번째 열에 만 관심이 있거나 구분 기호가 고정 된 경우 (즉, 가변 개수의 공백이 아님) awk / sed보다 깔끔하고 간결합니다.
  • 아주 우아합니다!

답변

.

로그 파일에 아래와 같은 텍스트가 포함되어 있다고 가정했습니다.

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 ~ ' 파일
  • " 열은 파이프로 구분되지 않음 | 하지만 열에 있습니다 ", 열이 공백으로 구분된다는 뜻인가요?
  • 샘플 입력과 출력이 더 좋습니다.

답변

아마도 sed를 사용하여 수행해야합니다. 아직 아무도 작성하지 않았으므로 :

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

OUTPUT

 foo | bar 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다