2개의 문자 구분 기호를 사용하여 잘라내기

2개의 문자 구분 기호를 사용하여 잘라내기

다음과 같이 cut to와 2개의 문자 구분 기호를 사용하여 많은 줄이 있는 파일을 처리하고 싶습니다.

1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

그러나 cut은 단일 문자만 허용합니다.

대신 cut -d'..'시도해 보지만 awk -F'..' "{echo $1}"작동하지 않습니다.

내 스크립트:

wget -O output.txt http://www.unicode.org/Public/emoji/6.0/emoji-data.txt                                                                             
sed -i '/^#/ d' output.txt                        # Remove comments                                                                                   
cat output.txt | cut -d' ' -f1 | while read line ;                                                                                                    
  do echo $line | awk -F'..' "{echo $1}"                                                                                                             
done  

답변1

awk필드 구분 기호가 2자를 초과할 때마다 정규식으로 처리됩니다. ..정규식으로 임의의 2개 문자를 나타냅니다. 이스케이프하려면 or with 를 .사용해야 합니다 .[.]\.

awk -F'[.][.]' ...
awk -F'\\.\\.' ...

(매개변수를 가져오거나 확장하려면 백슬래시 자체도 이스케이프 처리해야 합니다(적어도 gawk와 같은 일부 awk의 경우) \n.\b-F

귀하의 경우:

awk -F' +|[.][.]' '/^[^#]/{print $1}' < output.txt

어떤 경우 에라도,텍스트를 처리하는 쉘 루프 방지, 알아채다read이렇게 사용하면 안 된다, 저것echo임의의 데이터와 함께 사용하면 안 됩니다.그리고변수를 인용하는 것을 잊지 마세요.

답변2

나에게 도움이 된 샘플 테스트 스크립트는 다음과 같습니다.

#!/bin/sh

raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

for r in $raw
do
    f1=`echo "${r}" | cut -d'.' -f1`
    f2=`echo "${r}" | cut -d'.' -f2`
    f3=`echo "${r}" | cut -d'.' -f3`
    echo "field 1:[${f1}] field 2:[${f2}] field 3:[${f3}]"
done

exit

출력은 다음과 같습니다

field 1:[1F3C6] field 2:[] field 3:[1F3CA]
field 1:[1F3CF] field 2:[] field 3:[1F3D3]
field 1:[1F3E0] field 2:[] field 3:[1F3F0]

편집하다

Stéphane Chazelas의 댓글과 링크된 Q&A를 읽은 후 위의 내용을 다시 작성하여 삭제했습니다 loop.

제거할 방법을 못찾겠어요loop 그리고이러한 부분을 전달할 수 있는 변수로 유지하십시오(예: ; $f1$f2내 원래 답변). $f3원래 질문에서 출력이 무엇인지 아직 알 수 없습니다.

먼저 다음을 계속 사용하십시오 cut.

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | cut -d'.' -f1,3

그러면 다음이 출력됩니다.

1F3C6.1F3CA
1F3CF.1F3D3
1F3E0.1F3F0

.--output-delimiter=STRING표시된 문자열은 로 대체될 수 있습니다 .

다음으로, 출력을 더 효과적으로 제어하려면 sed대신 with를 사용하세요.cut

#!/bin/sh
raw="1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0"

printf '%s\n' "${raw}" | sed 's/^\(.*\)\.\.\(.*\)$/field 1 [\1] field 2 [\2]/'

그러면 다음이 렌더링됩니다.

field 1 [1F3C6] field 2 [1F3CA]
field 1 [1F3CF] field 2 [1F3D3]
field 1 [1F3E0] field 2 [1F3F0]

답변3

IFS를 사용하여 각 행을 분할하고 두 지점 사이의 필드를 삭제할 수 있습니다.

#/bin/sh
while IFS=\. read a _ b
do
     echo "field one=[$a] field two=[$b]"
done < "file"

구현하다:

$ ./script
field one=1F3C6 field two=1F3CA
field one=1F3CF field two=1F3D3
field one=1F3E0 field two=1F3F0

파일이 다음과 같다고 가정해 보겠습니다.

$ cat file
1F3C6..1F3CA
1F3CF..1F3D3
1F3E0..1F3F0

답변4

내가 만들었다패치필드 모드에서 작동하고 여러 연속 구분 기호를 단일 구분 기호로 처리하는 새로운 -m명령줄 옵션이 추가되었습니다. cut이는 기본적으로 OP의 문제를 상당히 효율적인 방식으로 해결합니다. 또한 이 패치가 coreutils 프로젝트에 병합되기를 바라면서 며칠 전에 이 패치 업스트림을 제출했습니다.

일부가 있습니다더 많은 생각공백 관련 기능을 더 추가하는 것에 대한 피드백을 갖고 cut이 모든 것에 대한 피드백을 제공하면 좋을 것입니다. 더 많은 패치를 구현하고 cut이를 업스트림에 제출하여 유틸리티를 더욱 다양하게 만들고 다양한 실제 시나리오에서 사용할 수 있게 만들고 싶습니다 .

관련 정보