개인 정보 (.txt)가 포함 된 파일이 있습니다. 터미널을 통해 파일에서 몇 가지 세부 정보 만 복사하여 새 .txt
파일에 넣을 수 있습니까?
예를 들어, 이것이 파일의 내용 인 경우 :
name : farah age : 23 phone number : 0123 education : degree
나이와 전화 번호 만 복사하여 새 .txt
파일로 출력하려면 어떻게해야합니까?
개인 정보 (.txt)가 포함 된 파일이 있습니다. 터미널을 통해 파일에서 몇 가지 세부 정보 만 복사하여 새 .txt
파일에 넣을 수 있습니까?
예를 들어, 이것이 파일의 내용 인 경우 :
name : farah age : 23 phone number : 0123 education : degree
나이와 전화 번호 만 복사하여 새 .txt
파일로 출력하려면 어떻게해야합니까?
답변:
이를 수행하는 몇 가지 방법이 있습니다. 파일의 구조가 알려진 경우를 사용할 수 있습니다 grep
. 이 grep
명령은 파일에서 특정 문구를 검색하고 해당 문구와 일치하는 줄을 반환합니다. 파일이 다음과 같다면
이름 : 샐리
생년월일 : 7.31.76
주소 : 1234 Main St.
SSN : 123-45-6789
당신은 실행할 수 있으며 grep Name info.txt
반환 Name: Sally
됩니다. 그런 다음 출력을 다른 파일 로 리디렉션 할 수 있습니다 . 그래서 전화
grep Name info.txt > info2.txt
줄을 새 파일 info2.txt에 출력합니다. 줄 바꿈을 추가하려면 할 수 있습니다
grep Address info.txt >> info2.txt
그렇지 않으면 파일을 덮어 씁니다.
입력 파일 details.txt
에 다음이 포함되어 있다고 가정합니다 .
name: farah
age: 23
phone number: 0123
education: degree
확장 된 grep을 사용하여 "name"및 "phone"행을 선택하고 출력을 new.txt로 리디렉션 할 수 있습니다.
grep -E "age:|phone number:" details.txt > new.txt
이렇게하면 다음과 함께 new.txt가 생성됩니다.
age: 23
phone number: 0123
작동 방식 :
Grep은 일치하는 줄만 인쇄합니다. -E
옵션을 사용하는 가능성을 제공합니다 확장 된 정규 표현식을 사용 |
(대안). 전체 패턴을 인용해야하므로 |
grep으로 해석됩니다. 그렇지 않으면 쉘은 해석을 시도합니다. 당신은 이것을 원하지 않습니다.
표시 한 파일에는 모든 세부 정보가 한 줄로 표시됩니다.
name : farah age : 23 phone number : 0123 education : degree
age :
명령에 하드 코드 등을 하드 코딩 할 수 있다고 가정 했지만 그 뒤에 나오는 텍스트는 다양하며 세부 사항이 주어진 순서대로 있지 않거나 인접하지 않을 수 있습니다.
grep
의 -o
플래그 를 사용하여 라인의 일부를 추출 할 수 있습니다 . 전체 줄이 아닌 일치하는 부분 만 인쇄합니다.
age :
및 phone number :
부분 을 포함 시키려면 -e
플래그를 사용하여 여러 개의 일치를 지정하거나 교대 할 수 있습니다 .
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
표현식 [^ ]*
은 공백이 아닌 문자 수를 의미하므로 age :
다음 공백까지의 문자와 일치 합니다.
교체 file
귀하의 세부 정보가 포함 된 파일의 이름으로. 다음과 같이 >
연산자 를 사용하여 출력을 새 파일로 리디렉션하여 새 파일을 작성할 수 있습니다 .
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
그렇게하면 출력이 표시되지 않습니다. 먼저 출력을 확인한 다음 리디렉션을 추가해야합니다.
다음은 대체 예입니다. 확장 정규 표현식을 사용하도록 -E
플래그를 사용합니다 grep
. 구문은 (pattern1|pattern2)
-이 일치 pattern1
및 / 또는 pattern2
. 둘 중 하나라도 발견되면 다른 것이 있는지 여부에 관계없이 인쇄됩니다. 나는 이제 +
앞의 문자 중 *
0 이상 을 의미하는 대신 앞의 문자 중 하나 이상 을 의미하고 있습니다. 이러한 맥락에서, 그들은 똑같이 잘 작동합니다.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
age :
및 phone number:
부분 을 생략하려면 -P
플래그 grep
를 사용하여 Perl 호환 정규식 사용 을 요청할 수 있습니다. 이것은 교대를 지원 하고 주어진 패턴 후에 텍스트를 일치시키는 방법을 지원합니다 :
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
텍스트의 형식을 다르게하려면 다음 sed
과 같이 사용할 수 있습니다 .
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
이것은 age
앞에 오는 것에 달려 phone number
있으므로 그렇지 않은 경우 적절하게 조정하십시오. 주문에 의존 할 수 없다면 다음과 같이 매우 복잡한 명령을 사용할 수 있습니다.
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
이렇게하면 선이 재정렬되어 phone number :
섹션이 모든 선에서 첫 번째로 오게 한 다음 두 번째 교체를 수행하여 원하는 세부 사항을 선택합니다. 여기에 사용 된 기술 은 muru의 답변 입니다.
sed
이전 설명에서 다루지 않은 명령 에 대한 참고 사항-r
더 읽기 쉬운 명령에 확장 정규식을 사용하십시오 (GNU 는 동일한 의미로 sed
이해 -E
합니다)s/old/new/
교체 old
로new
(pattern)
저장 pattern
하여 나중에 참조하기 위해 \1
또는 \2
등 (캡처 그룹이 발생할 수있는 왼쪽에서 오른쪽의 순서에 해당하는 -주의 sed
! 만이 7까지 유지됩니다)..
따라서 모든 문자 .*
는 임의의 수의 문자를 나타냅니다.;
쉘에서와 같이 명령을 분리합니다.