'cut'명령어를 동일한 순차적 구분 기호로 처리하는 방법은 무엇입니까?


308

열 기반의 '공간'조정 텍스트 스트림에서 특정 (네 번째) 필드를 추출하려고합니다. cut다음과 같은 방법으로 명령 을 사용하려고합니다 .

cat text.txt | cut -d " " -f 4

불행히도 cut여러 공백을 하나의 구분 기호로 취급하지 않습니다. 나는 awk를 통해 파이프 수

awk '{ printf $4; }'

또는 sed

sed -E "s/[[:space:]]+/ /g"

공백을 접을 수 있지만 cut기본적으로 여러 구분 기호 를 처리 할 수있는 방법이 있는지 알고 싶습니다 .



답변:


546

시험:

tr -s ' ' <text.txt | cut -d ' ' -f4

로부터 tr매뉴얼 페이지

-s, --squeeze-repeats는 반복되는 문자의 각 입력 순서를 대체합니다.
                        한 번의 발생으로 SET1에 나열됩니다.
                        그 캐릭터의

24
cat여기에 필요가 없습니다 . 에 < text.txt직접 전달할 수 있습니다 tr. en.wikipedia.org/wiki/Cat_%28Unix%29#Useless_use_of_cat
arielf

1
그것이 더 간단하지는 않지만 병합 할 예정이라면 잘라 내기를 포기 -d하고 여러 문자에서 탭으로 바로 변환 할 수 있습니다 . 예를 들면 : 여기에 내 디스플레이를 자동으로 내보내는 방법을 찾고있었습니다.who am i | tr -s ' ()' '\t' | cut -f5
Leo

이것은 awk 솔루션과 달리 선행 / 후행 공백을 제거하지는 않습니다 (원하지 않을 수도 있지만 일반적으로 그렇지 않습니다). awk 솔루션은 훨씬 더 읽기 쉽고 덜 장황합니다.
n.caillou

-1 경고 : 이는 시퀀스 델리 미터를 하나로 취급하는 것과 같은 것이 아닙니다. 비교 echo "a b c" | cut -d " " -f2-,echo "a b c" | tr -s " " | cut -d " " -f2-
user541686

96

당신이 당신의 질문에 의견을 말할 때, awk정말 갈 길입니다. kev의 답변에서 볼 수 있듯이 공간을 짜는 것과 cut함께 사용할 수 있습니다 .tr -s

그러나 앞으로 독자들을 위해 가능한 모든 조합을 살펴 보겠습니다. 설명은 테스트 섹션에 있습니다.

tr | 절단

tr -s ' ' < file | cut -d' ' -f4

어 wk

awk '{print $4}' file

세게 때리다

while read -r _ _ _ myfield _
do
   echo "forth field: $myfield"
done < file

sed

sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' file

테스트

이 파일이 주어지면 명령을 테스트 해 봅시다.

$ cat a
this   is    line     1 more text
this      is line    2     more text
this    is line 3     more text
this is   line 4            more    text

tr | 절단

$ cut -d' ' -f4 a
is
                        # it does not show what we want!


$ tr -s ' ' < a | cut -d' ' -f4
1
2                       # this makes it!
3
4
$

어 wk

$ awk '{print $4}' a
1
2
3
4

세게 때리다

필드를 순차적으로 읽습니다. _우리는 이것을 사용하여 이러한 필드를 무시하기위한 "정크 변수"로서의 이탈 변수임을 나타냅니다. 이런 식으로, 우리 $myfield는 파일 사이의 공간에 관계없이 파일의 4 번째 필드로 저장 합니다.

$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a
4th field: 1
4th field: 2
4th field: 3
4th field: 4

sed

공백이없는 세 그룹의 공백을 잡습니다 ([^ ]*[ ]*){3}. 그런 다음, 네 번째 필드로서 공백이 될 때까지 오는 모든 것을 포착하여 최종적으로로 인쇄됩니다 \1.

$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a
1
2
3
4

2
awk우아하고 단순 할뿐만 아니라 tr누락 된 VMware ESXi에도 포함되어 있습니다.
user121391

2
@ user121391 또 다른 이유가 있습니다 awk!
fedorqui 'SO 중지 피해'

@fedorqui "정크 변수"라는 밑줄을 들어 본 적이 없습니다. 이에 대한 더 많은 통찰력 / 참조를 제공 할 수 있습니까?
BryKKan

1
@BryKKan Greg 's에서 그것에 대해 배웠 습니다. 파일 (데이터 스트림, 변수)을 라인 단위 (및 필드 단위)로 읽는 방법은 무엇입니까? : 일부 사람들은 필드를 무시하기 위해 버리기 변수 _를 "정크 변수"로 사용합니다. read우리가 그것에 들어가는 것을 신경 쓰지 않으면 단일 명령 에서 두 번 이상 사용할 수 있습니다 . 그것은 아무것도 할 수있다, 그것은 어떻게 든 대신에 표준이되었다 그냥 junk_varwhatever:
'SO 정지 해치지'fedorqui

25

가장 짧고 친근한 솔루션

의 너무 많은 제한에 좌절 한 후 cut, 나는 cuts"스테로이드 컷 (cut on steroids)"을 요구하는 내 자신의 대체물을 썼습니다 .

절단 은이문제와 기타 여러 가지 절단 / 붙여 넣기 문제에대한 가장 미니멀리스트 솔루션을 제공합니다.

이 특정 질문을 다루는 많은 예 중 하나가 있습니다.

$ cat text.txt
0   1        2 3
0 1          2   3 4

$ cuts 2 text.txt
2
2

cuts 지원합니다 :

  • 파일에서 가장 일반적인 필드 구분 기호 자동 감지 (+ 기본값을 무시하는 기능)
  • 다중 문자, 혼합 문자 및 정규식 일치 구분 기호
  • 구분 기호가 혼합 된 여러 파일에서 열 추출
  • 줄의 시작과 더불어 줄의 끝에서 (음수를 사용하여) 오프셋
  • 열의 자동 병렬 붙여 넣기 ( paste별도의 호출 필요 없음 )
  • 필드 재정렬 지원
  • 사용자가 개인 환경 설정을 변경할 수있는 구성 파일
  • 사용자 친 화성 및 미니멀리스트 필수 타이핑에 중점을 둡니다.

그리고 훨씬 더. 어느 것도 표준에 의해 제공되지 않습니다 cut.

참조 : https : //.com/a/24543231/1296044

소스 및 설명서 (무료 소프트웨어) : http://arielf.github.io/cuts/


4

이 Perl one-liner는 Perl이 awk와 얼마나 밀접한 관련이 있는지 보여줍니다.

perl -lane 'print $F[3]' text.txt

그러나 자동 @F분할 배열은 인덱스에서 시작 $F[0]하는 반면 awk 필드는$1


3

cut내가 아는 버전으로 는 불가능합니다. cut는 구분 기호가 공백이 아니고 /etc/passwd필드 수가 고정 된 파일을 구문 분석하는 데 주로 유용 합니다. 행의 두 구분 기호는 빈 필드를 의미하며 공백에도 적용됩니다.

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