.tsv 파일로 가득 찬 디렉터리가 있고 각 파일에 대해 grep 명령을 실행하여 특정 텍스트 줄 집합을 추출한 다음 유사한 파일 이름을 가진 관련 텍스트 파일에 저장하려고 합니다. 예를 들어 파일 하나만 grep하는 경우 grep 명령은 다음과 같습니다.
grep -h 8-K 2008-QTR1.tsv > 2008Q1.txt
하지만 다음과 같은 tsv 파일 목록이 있습니다.
2008-QTR1.tsv
2008-QTR2.tsv
2008-QTR3.tsv
2008-QTR4.tsv
2009-QTR1.tsv
2009-QTR2.tsv
2009-QTR3.tsv
...
grep 후에는 다음과 같이 저장해야 합니다.
2008Q1.txt
2008Q2.txt
2008Q3.txt
2008Q4.txt
2009Q1.txt
2009Q2.txt
2009Q3.txt
어떤 아이디어가 있나요?
답변1
ksh93/bash/zsh에서 간단한 for
루프 및 매개변수 확장을 통해:
for f in *-QTR*.tsv
do
grep 8-K < "$f" > "${f:0:4}"Q"${f:8:1}".txt
done
이번에 grep
는 파일(파일 이름에 "-QTR" 및 파일 이름 끝에 ".tsv"가 있어야 하는 와일드카드 패턴을 기반으로 파일 목록이 생성됨)을 실행하면 출력이 파일로 리디렉션됩니다. 이름을 기준으로 신중하게 구성되었습니다.
- 파일 이름의 처음 4자 - 연도
- 이 편지
Q
- 파일명의 9번째 문자 - Quarter
답변2
필수 POSIX sh
변형:
#! /bin/sh -
ret=0
for file in [[:digit:]][[:digit:]][[:digit:]][[:digit:]]-QTR[1234].tsv; do
base=${file%.tsv}
grep 8-K < "$file" > "${base%%-*}Q${base##*-QTR}".txt || ret=$?
done
exit "$ret"
답변3
다른 옵션
for f in 200{8..9}-QTR{1..4}.tsv; do
grep "pattern" $f > $(sed "s/[-RTtsv]*//g" <<< $f)txt;
done
연습: 파일 이름 목록을 생성하기 위한 확장명 설정
200{8..9}-QTR{1..4}.tsv
다음으로 확장
2008-QTR1.tsv 2008-QTR2.tsv 2008-QTR3.tsv 2008-QTR4.tsv 2009-QTR1.tsv 2009-QTR2.tsv 2009-QTR3.tsv 2009-QTR4.tsv
지금까지 매년, 매 분기마다 해야 할 일은 다음과 같습니다.
20{08..19}-QTR{1..4}.tsv
목록을 반복 for..do..done
하고 파일에서 찾고 있는 패턴을 추출합니다.
grep "pattern" $f
원하지 않는 문자를 제거 sed
하고 접미사를 추가하여 txt
형성된 새 파일 이름 으로 리디렉션합니다.
$(sed "s/[-RTtsv]*//g" <<< $f)txt
또는
$(sed "s/[-RT]*//g" <<< ${f%%.*}.txt)
답변4
명시적인 루프를 피하려면 다음과 같은 해결 방법이 있습니다. 어쩌면 누군가가 그것을 향상시킬 수 있습니다. 이렇게 생겼습니다.
ls -1 *.tsv | xargs -n1 -I'{}' bash -c 'f="{}";grep 8-K $f > ${f//[^0-9Q]/}.txt'
- 엘에스처리하려는 파일만 나열
- 매개변수이러한 각 파일을 하나씩 처리합니다(-n1)
- ㅏ세게 때리다문자열을 처리할 수 있도록 셸을 시작합니다(포인트 5 참조).
- 파일 이름을 변수로 설정$f
- ${f//[^0-9Q]/}.txt 파일 이름에 필요하지 않은 문자를 제거하십시오(이는 귀하의 예에만 해당됩니다).
장점: - 간단한 하나의 라이너
단점: - 처리된 각 파일에 대해 bash 프로세스를 시작합니다.
Bash를 사용하지 않는 비슷한 솔루션이 있을 수도 있지만 잘 모르겠습니다(예: 이 경우 eval이 작동하지 않아야 함).