같은 디렉토리에 여러 개의 파일이 있는데 15일부터 20일까지 연속적인 간격으로 특정 줄을 인쇄하고 싶습니다.
단일 파일의 경우 이는 작동 head -n20 file.txt | tail -n6
하지만와일드카드 패턴으로 작동하게 하려면 어떻게 해야 하나요?, 예를 들어 해당 디렉토리의 모든 txt 파일에 대해 *.txt
?
head -n20 *.txt | tail -n6 # this only crops results of head -n20
편집 1: 해결 방법도 알고 있지만 for
와일드카드에서도 작동하는 통합된 방식으로 여러 작업에 대한 파이프라인을 정의하는 방법을 배우고 싶습니다.
ps에는 wildcards ==> file.txt <==
와 결합할 때 제공되는 것과 같은 표준 헤더가 있을 수 있는데 , 이는 너무 많은 것을 요구합니다.head
tail
pps는 우분투를 사용하지만 UNIX 전체 접근 방식이 더 좋습니다.
답변1
이 한 줄짜리는 어떻습니까?
for f in *.txt; do echo -e "\n==> $f <=="; head -n 20 "$f" | tail -n 6; done
현재 디렉터리에서 실행되면 glob을 .txt
사용하여 *.txt
모든 파일을 반복한 다음 헤더를 인쇄하고 각 파일에 대해 헤드 및 테일 작업을 수행합니다.
답변2
참고하시기 바랍니다.기준head
여러 파일 이름을 인수로 사용하고 이러한 ==> filename <==
헤더를 출력할 수 있습니다.기준tail
하나의 파일 이름만 인수로 사용할 수 있습니다. 여러 파일 이름이 전달되면 동작이 지정되지 않습니다.
여기서는 쉘 루프 대신 다음 명령을 사용할 수 있습니다 gawk
.
gawk 'BEGINFILE{print sep"==> "substr(FILENAME, 3)" <=="; sep = "\n"}
FNR >= 15
FNR == 20 {nextfile}' ./*.txt
이를 함수로 바꿀 수 있습니다:
linerange() (
min=$1 max=$2
shift 2
exec gawk -v min="$min" -v max="$max" -e '
BEGINFILE{print sep"==> "FILENAME" <=="; sep = "\n"}
FNR > max {nextfile}
FNR >= min' -E /dev/null "$@"
)
그런 다음:
linerange 15 20 *.txt
gawk
, 다른 질문과 마찬가지로 awk
양식의 매개변수는 var=value
입력 파일 이름이 아닌 변수 할당으로 처리됩니다. 이는 일부 .txt
파일이 제대로 작동하지 않는 경우( 또는 ... foo=bar.txt
과 같은 더 짜증나는 부작용이 발생할 수 있음 )를 의미합니다.ARGC=0.txt
ORS=.txt
첫 번째 경우에는 접두사 ./
(나중에 제거함)를 사용하여 이 문제를 해결하고 substr(FILENAME, 3)
, 두 번째 경우에는 (빈 파일: /dev/null을 전달하지만 -E
매개변수를 사용할 때 할당이 처리되지 않습니다).-E