세미 초보자. 자동화를 위해 awk 스크립트를 사용해 보세요. 이론적으로는 간단해야 합니다.
모두 .lst로 끝나는 파일 세트입니다. 각 파일에는 특정 문자열이 포함된 줄(수백 개 중)이 있습니다. "Wall"이라는 단어를 예로 들어 보겠습니다. 내가 하고 싶은 것은 각 줄이 (i) 파일 이름과 (ii) 출력 문자열로 끝나는 파일로 끝나는 것입니다. "부분"이 개별적으로 작동하지만 (공통 출력 파일을 생성하기 위해) 함께 결합하는 방법을 아직 파악하지 못했습니다.
따라서 3개의 *.lst 파일(file1.lst, waste.lst, blah.lst)이 있다고 가정해 보겠습니다. 다음과 같은 방법을 사용하여 파일 이름을 파일로 출력할 수 있습니다(의심할 여지 없이 더 좋은 방법이 있지만 작동합니다...).
ls -l *.lst | awk '{ print "File: " $9 }' > filenames.dat
또한 다음과 같은 방법을 사용하여 각 *.lst 파일에 "Wall"이 포함된 줄을 공통 파일로 쉽게 출력할 수 있습니다.
awk '/Wall/{print}' *.lst > wallvals.dat
다양한 방법으로 두 가지를 후처리하고 병합할 수 있지만 awk를 사용하여 한 줄로 이 모든 작업을 수행하는 방법을 알아내고 싶습니다. 따라서 생성된 출력 파일은 다음과 같습니다.
File: file1.lst Wall data 4.54
File: trash.lst Wall data 3.44
File: blah.lst Wall data 333.66
나는 다양한 파이핑 방법을 시도하거나 awk 매개변수 내에 다양한 비트를 중첩하려고 시도했지만 아무것도 작동하지 않았습니다(오류 메시지를 생성하는 것이 목적이 아닌 이상).
미리 명확한 지침을 이해하십시오 ...
답변1
현재 처리 중인 파일의 파일명은 awk
특수변수에서 확인할 수 있습니다 FILENAME
. 즉, awk
두 번째 명령을 다음과 같이 조정할 수 있습니다.
awk '/Wall/ { printf "%s:%s\n", FILENAME, $0 }' *.lst
아니면 마음에 들지 않는다면 printf
,
awk '/Wall/ { print FILENAME ":" $0 }' *.lst
또는 출력 필드 구분 기호를 사용 OFS
하여
awk -v OFS=: '/Wall { print FILENAME, $0 }' *.lst
그러면 파일 이름과 패턴과 일치하는 행이 출력되며 그 사이에 콜론이 포함됩니다.
이는 grep
다음 명령과 동일한 효과를 갖습니다.
grep -H 'Wall' *.lst
...여기서 검색 문자열이 확장 정규 표현식이 아닌 기본 정규 표현식으로 사용된다는 점에서 약간의 차이가 있습니다(그러나 이 경우에는 중요하지 않습니다). 이 -H
옵션은 표준이 아니며 grep
여러 파일 이름이 지정된 경우에는 필요하지 않습니다. grep 'Wall' /dev/null *.lst
동일한 명령을 작성하는 보다 표준적인 방법입니다(여러 경로 이름이 제공되면 유틸리티는 항상 일치하는 각 파일 이름을 출력합니다).
네가 원한다면정밀한질문에서 언급한 출력 형식을 확인한 후 printf
형식 문자열을 수정하세요.
awk '/Wall/ { printf "File: %s\t%s\n", FILENAME, $0 }' *.lst
또는,
awk '/Wall/ { print "File: " FILENAME "\t" $0 }' *.lst
File:
그러면 파일 이름, 탭 및 줄이 뒤에 오는 문자열이 출력됩니다 .
첫 번째 명령에 관해서는 다음과 같습니다.일반적으로 말하면구문 분석된 출력은 나쁜 생각입니다 ls
. 부분적으로는 거의 항상 불필요하고 보기 흉하기 때문이며, 부분적으로는 출력이 ls
주로 보기 위한 것이기 때문입니다(파일 이름에 추가 형식이 적용될 수 있음). 이는 거의 항상 유효한 파일 이름을 모두 읽을 수 없음을 의미합니다. 바라보다왜 `ls`를 구문 분석하지 *않나요*(그리고 어떻게 수행합니까)?