grep, awk 및 csv를 사용하여 텍스트 파일에서 정보 추출

grep, awk 및 csv를 사용하여 텍스트 파일에서 정보 추출

다음 코드를 사용하여 여러 텍스트 파일(foo*.txt)에서 정보를 추출합니다.

for file in foo*.txt; do 
grep "some_text" $file | tail -n5 | awk '{print $2}' >> bar.csv
done

이 주석은 여러 파일(foo*.txt)에서 내가 원하는 숫자를 인쇄합니다. 파일 이름(csv 파일의 한 열에 있음)과 번호(csv 파일의 다음 열에 있음)를 모두 인쇄하려고 할 때 터미널에서 다음을 시도했습니다.

for file in foo*.txt; do 
echo $file
grep "some_text" $file | tail -n5 | awk '{print $2}' >> bar2.csv 
done

그러면 터미널에 있는 파일 이름이 인쇄됩니다. csv 파일에는 내가 원하는 숫자가 포함되어 있습니다. 파일 이름이 한 열에 인쇄되고 추출된 숫자가 csv 파일의 다음 열에 인쇄되도록 이 코드를 어떻게 수정할 수 있습니까?

이 코드의 또 다른 문제는 정렬 문제입니다. 예를 들어 파일 이름 foo_01_s.txt, foo_02_s.txt, foo_03_s.txt.....foo_100_s.txt를 고려해 보세요. 정보를 추출하려면(위 설명을 사용하여) 마지막 파일(foo_100_s.txt)이 foo_99_s.txt 뒤에 오지 않습니다.

Python/Perl을 사용하는 솔루션도 도움이 될 것입니다.

답변1

>>당신은 현재 명령의 일부만 리디렉션한다는 것을 이해해야 합니다 . 기본적으로는 으로 시작 grep하고 몇 번 파이프한 명령의 결과인 숫자입니다. echo $file는 별도의 명령(사용 ;)이므로 일반적으로 stdout으로 연결됩니다. 당신이 해야 할 일은 전체 루프 이후에 리디렉션하는 것뿐입니다.

for file in foo*.txt; do 
    echo $file
    grep "some_text" $file | tail -n5 | awk '{print $2}'
done > bar2.csv

파일을 "버전" 정렬하려면(적절한 이름임) 정렬 후 나열할 수 있습니다.

for file in $(ls foo*.txt | sort -V); do

작은 작업을 빠르게 실행하려면(~1000개 파일의 경우 몇 분 정도) 괜찮습니다.

편집하다

귀하의 의견에 따라 몇 가지 해결책이 있습니다. 나는 당신이 원하는 것 같아요 :

file1 1
      2
      3

등. 그냥 삭제 echo하고 에코 라인을 수정하세요.

for file in foo*.txt; do 
    grep "some_text" $file | tail -n5 | awk -v f=$file '{if(NR==1) {printf("%-20s %-5s\n",f,\$2)} else {printf("%-20s %-5s\n","",$2)}}'
done > bar2.csv

나는 awk나를 위해 인쇄를 하게 했다. -v를 사용하면 f. 인쇄하려면 printf구문에 익숙해지세요(셸에서 사용할 수 있습니다 man printf. 기본적으로 두 개의 필드, 즉 하나는 20이고 다른 하나는 5이고 그 사이에 공백이 있다고 가정합니다. 왼쪽 음수 기호는 양쪽 맞춤입니다. 사용해 볼 수 있습니다. 이렇게 하면 됩니다. 초기 문제를 해결했습니다. 이제 해당 단일 라인을 파이프할 수 있습니다.

파일을 다음과 같이 만들고 싶다면:

file1,1
file1,2
...
file2,1

if내 명령문에 해당 내용을 삭제 awk하거나 초기 솔루션을 에코로 남겨둘 수 있습니다.

echo -n "$file,"

개행 문자가 인쇄되지 않는지 확인 -n합니다.

관련 정보