for 루프 내에서 실행되는 동안 wc로 파이프된 ls의 결과를 어떻게 얻나요?

for 루프 내에서 실행되는 동안 wc로 파이프된 ls의 결과를 어떻게 얻나요?

따라서 데이터를 파일에 덤프하는 대신 단일 명령으로 만든 다음 파일을 cat하고 출력을 wc -l로 파이프했습니다. 전체 코드 줄은 다음과 같습니다.

for file in `grep Rawdata freeze2-1.out | awk '{print $6}'`
 do
  ls -1 /appdata/frozen_files/$file | wc -l
 done

그러나 출력은 전체 출력의 합계가 아닌 행당 개수를 제공합니다. 어쨌든 모든 파일에 대해 단일 숫자의 출력을 가져오는 동안 이 작업을 수행할 수 있습니까? 아니면 파일로 리디렉션하고 다른 단계를 수행해야 합니까?

답변1

Freeze2-1.out 파일에서 필드 6으로 명명된 디렉터리의 총 파일 수를 계산하려고 하지만 파일의 해당 줄 어딘가에 "Rawdata"가 나타나는 경우에만 해당됩니다.

wc -l원본 게시물의 주요 오류는 단순히 개별 행 계산을 요청한 논리 또는 배치의 실수입니다.~에전체 루프에서 제공되는 총 행 수를 요청하는 루프입니다. 이것이 대부분의 기존 답변이 수정되는 것입니다.

"집에서 놀 수 있도록" 샘플 Freeze2-1.out 파일을 만들었습니다. 여기에 넣은 내용은 다음과 같습니다.

Rawdata 2 3 4 5 file1
Rawdata 2 3 4 5 file2
Rawdata 2 3 4 5 file3

나도 하나 채웠어비교적"appdata/frozen_files"라는 디렉터리는 위의 필드 6을 기반으로 합니다. 실제 경로는 다음과 같습니다.순수한/appdata/frozen_files로 시작하는 경로입니다. file1에 1개, file2에 2개, file3에 3개 총 6개의 파일을 넣었습니다.

제가 제안하고 싶은 첫 번째 개선 사항은 awk가 패턴 일치를 수행할 수 있으므로 grep와 를 결합 하는 것입니다 awk.로마 페레크레스트이것이 그들이 대답한 내용이기도 합니다:

awk '/Rawdata/ { print $6 }' freeze2-1.out

예시 출력은 다음과 같습니다:

file1
file2
file3

여기서는 awk가 공백, 탭 및 개행을 기준으로 필드를 분할하기 때문에 특히 필드 6을 인쇄한다는 것은 출력의 각 줄에 공백 없이 하나의 단어가 있다는 것을 의미한다는 점을 지적하겠습니다.

디렉터리의 파일 수를 계산하는 방법에는 여러 가지가 있습니다. 사용된 ls -1 | wc -l것은하지만 줄 바꿈이 포함된 파일 이름의 특수한 경우에는 실패합니다. 이러한 파일을 수동으로 생성할 수 있습니다 touch $'file\nname'. awk는 줄 바꿈으로 구분된 입력 줄을 읽기 때문에 여기서는 특별한 경우를 만나지 않지만 언급하고 싶었습니다. 예를 들어:

# create the file
$ touch $'file\nname'

# check the listing; looks okay so far
$ ls -1
appdata
file?name
freeze2-1.out

# count them up
$ ls -1 | wc -l
4 

# woops! should be 3!

따라서 디렉터리의 파일 수를 계산하는 두 가지 다른 방법을 보여 드리겠습니다.

첫 번째 방법은 set내장 함수를 사용하여 인수를 가져와 $1, $2, $3 등의 위치 인수로 변환합니다.

$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out)
  do
    set -- "appdata/frozen_files/${file}/"*
    sum=$((sum + $#))
  done
$ echo "$sum"
6

이는 카운터를 sum0으로 초기화한 다음 awk 출력의 파일 이름을 반복합니다. 이는 set인용된 디렉토리 경로와 *그 디렉토리의 모든(숨겨지지 않은) 파일로 확장되는 쉘 glob으로 호출됩니다. 이는 ls -1숨겨진 파일(마침표로 시작하는 파일)을 제외하는 동작과 일치합니다. 인수의 수는 $#루프에 추가 sum하고 마지막에 인쇄하는 특수 변수에 의해 제공됩니다.

배열을 지원하는 쉘의 경우 두 번째 접근 방식은 와일드카드 파일 이름을 배열에 넣은 다음 배열 요소 수를 계산하는 것입니다.

$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out )
  do
    n=("appdata/frozen_files/${file}"/*)
    sum=$((sum + ${#n[@]}))
  done
$ echo "$sum"
6

답변2

단어 수를 끝으로 이동합니다.

for file in $(grep Rawdata freeze2-1.out | awk '{print $6}')
 do
  ls -1 /appdata/frozen_files/$file
 done | wc -l

또는 합계;

C=0
for file in $(grep Rawdata freeze2-1.out | awk '{print $6}')
 do
  C=$[$C+$(ls -1 /appdata/frozen_files/$file | wc -l)]
 done
echo $C;

또는 파일 구조가 패턴(또는 정규식)과 일치할 수 있으면 find를 사용할 수도 있습니다.

find /appdata/frozen_files/ -iname '*.raw' |wc -l

관련 정보