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