두 개의 큰 따옴표 사이에 sed get 하위 문자열 사용


14

나는 파일이있다

xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
"/home/path/to/file1": Permission denied (13) rsync:
"/home/path/to/file2": Permission denied (13) rsync:
"/home/path/to/file3": Permission denied (13)

이제 파일 경로 만 추출하여 다른 파일에 저장하려고합니다. 출력 파일은 다음과 같습니다

/home/path/to/file 
/home/path/to/file1 
/home/path/to/file2
/home/path/to/file3

sed 또는 awk를 사용하여 어떻게 할 수 있습니까?

시도 sed -n '/"/,/"/p' myfile했지만 작동하지 않습니다.


3
마감 투표를하는 사람들에게 — 이것은 어떻게 주제를 벗어난 것일 수 있습니까? 쉘 프로그래밍에 관한 것입니다 !! 스택 오버플로에 대한 주제 인 프로그래밍입니다!
Jonathan Leffler

2
스택 오버플로에 오신 것을 환영합니다. 보시다시피, 때때로 가려운 방아쇠를 가진 사람들이 폐쇄에 대한 나쁜 이유와 함께 완벽하게 좋은 질문 (예 : 이와 같은)을 닫는 데 문제가 있습니다. 그것은 자주 발생하지는 않지만 (또는 시간에 문제를 자주 보지 못하지만) 발생합니다. 너무 오래 전에 FAQ 를 읽는 것을 잊지 마십시오 .
Jonathan Leffler

답변:


17

rsync 명령의 stderr를 awk 스크립트로 파이프 할 수 있습니다.

awk -F '"' '{print $2}' 

또는 다음과 같은 잘라 내기 명령으로 :

cut -d'"' -f2

2
또는 짧은 :cut -d\" -f2

@AndersJohansson : 감사합니다. 컷 명령도 추가했습니다.
anubhava

파일 경로의 필드 번호가 $ 2 또는 f2로 고정되어 있지 않음을 알 수 있듯이 이것이 작동하지 않을 것이라고 생각합니다. 감사합니다!

실제로 rsync는 항상 stderr 사이 ""stderr에서 파일 경로를 먼저 씁니다 .
anubhava

1
@ Jam88 : 사실, 그것은 anubbhava가 쓴 방식 때문에 작동합니다. 필드 구분 기호는 큰 따옴표로 설정됩니다. 그것은 첫 번째 큰 따옴표 (아마도 빈 문자열)까지의 모든 것이 $1; 첫 번째와 두 번째 큰 따옴표 사이의 모든 것은 $2; 두 번째 큰 따옴표 뒤에있는 모든 것은 $3( $4, ...)에 있습니다. 파일 이름은 항상 처음 두 개의 큰 따옴표 사이에 있으므로이 솔루션이 작동해야합니다 (테스트 할 때 수행).
Jonathan Leffler

6

사용 sed:

sed 's/^[^"]*"\([^"]*\)".*/\1/'

그것은 선의 시작, 일련의 따옴표가 아닌, 큰 따옴표, 일련의 따옴표가없는 것, 큰 따옴표 및 그 밖의 다른 것을 포착하여 캡처 된 자료로 대체합니다.

$ sed 's/^[^"]*"\([^"]*\)".*/\1/' <<'EOF'
> xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
> "/home/path/to/file1": Permission denied (13) rsync:
> "/home/path/to/file2": Permission denied (13) rsync:
> "/home/path/to/file3": Permission denied (13)
> EOF
/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3
$

GNU sed를 사용하여 RHEL 5 Linux에서 테스트 하되 7th Edition UNIX ™ 버전에서 작동했던 기능 만 사용하십시오 sed.

덧붙여서, 약간 간단한 방법은 두 개의 대체 명령을 사용하는 것입니다. 첫 번째 큰 따옴표를 포함하여 모든 것을 빈 문자열로 변경하십시오 (0 개 이상의 따옴표가 아닌 순서와 큰 따옴표가 이어짐). 이제 첫 번째 큰 따옴표 뒤에있는 것을 모두 변경하십시오.

sed 's/^[^"]*"//; s/".*//'

또한, 시도한 명령 (`sed -n '/ "/, /"/ p')은 줄을 전혀 편집하지 않고 큰 따옴표를 포함하는 한 줄에서 큰 따옴표를 포함하는 다음 줄로 인쇄합니다. 그것이 당신을 위해 효과가없는 것처럼 보이는 이유입니다. 그것은 당신이 요구 한 것을했지만, 당신이 그것을 요구 한 것은 당신이하고자하는 것이 아니 었습니다.

효율성 측면에서 성능에는 큰 차이가 없을 것입니다. 유지 보수의 용이성 측면에서, 나는 후자가 뇌 세포에 대한 과세가 적다고 생각합니다.


1

grepPerl-regexp 를 지원하는 버전 인 경우 :

grep -oP '(?<=")/home/.*?(?=")' file >> anotherfile

결과 :

/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3

원하는 경우 복식 사이의 모든 것을 일치시키기 위해 덜 엄격하게 만들 수도 있습니다.

grep -oP '(?<=")[^"]*' file >> anotherfile

나중에 줄에 여분의 큰 따옴표가있는 경우를 대비 .*하여 욕심없는 것을 만들어야 .*?합니까? 또는 [^"]*대신에 사용 .*하시겠습니까?
Jonathan Leffler

-1

>> 연산자를 사용하여 출력을 파일에 저장하십시오.

처럼

grep -r "pattern" * >> file.txt

sed를 사용하여 특정 시나리오에 맞게 변경하십시오.

>> filename

명령에


grep -r인수에 나열된 디렉토리 (을 통해 반복 검색을한다 *). 어떤 패턴을 염두에두고 있는지 명확하지 않지만 grep전체 라인을 선택합니다. 연습의 목적은 라인의 일부에서 정보를 수집하는 것입니다. GNU를 사용하고 있다면 그렇게 할 수 grep있는 방법이 있습니다 ( -o). 이것들은 비표준입니다 (GNU가 사실상 표준을 정의하는 경우 제외). PCRE 정규 표현식을 사용하는 것과 유사하게; 그것들은 또 다른 GNU 확장입니다. GNU를 가지고 grep있고 GNU grep를 기본적으로 사용할 수없는 플랫폼에서 작업 할 계획 이 없다면 괜찮습니다 .
Jonathan Leffler

미안하지만, 그는 일반적으로 출력을 파일에 넣는 방법을 알고 싶다고 생각했으며 grep은 단지 예일뿐입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.