디렉터리에서 기능별 파일 제공

디렉터리에서 기능별 파일 제공

몇 가지 특정 파일을 두 개로 그룹화하여 올바른 순서로 프로그램에 공급해야 합니다.

만약 내가 가지고 있다면

A_file.txt
B_file.txt
C_file.txt
D_file.txt

파일 A와 B가 먼저 처리되고 그 다음 C와 D 등이 처리되도록 이를 프로그램에 공급해야 합니다. 본질적으로:

for i in *.txt; do 
   some_program A_file.txt B_file.txt > output_AB
   some_program C_file.txt D_file.txt > output_CD

위의 내용이 의미가 없다는 것을 알고 있지만 요점을 설명하기 위한 것입니다. 기본적으로 .txt폴더의 모든 파일을 반복 하되 한 번에 두 개의 파일을 프로그램에 공급한 후 다음 두 파일로 이동합니다.

아직도 배우고 있습니다. 정말 감사합니다.

답변1

#!/bin/sh

set -- *_file.txt

until [ "$#" -lt 2 ]; do
    process "$1" "$2" >"output_${1%_file.txt}${2%_file.txt}"
    shift 2
done

그러면 질문의 이름과 일치하는 파일 이름 와일드카드 패턴을 기반으로 관심 있는 파일 이름 목록으로 위치 매개변수가 설정됩니다. 그런 다음 목록에 두 개 미만의 이름이 남을 때까지( $#위치 인수 목록의 길이) 루프를 사용하여 이 목록을 반복합니다.

각 반복에서 목록의 처음 두 요소가 처리된 $1다음 $2를 사용하여 목록에서 제거됩니다 shift 2.

처리된 출력은 이름이 지정된 파일로 리디렉션되고 output_그 뒤에는 두 파일 이름의 변수 부분( _file.txt각 파일의 정적 문자열 앞에 오는 항목)이 연결됩니다.

이는 이름을 사전순으로 정렬하는 방식(와일드카드 패턴의 확장을 사용하면 됨)으로 파일 이름이 지정되어 질문에 표시된 대로 쌍을 이룰 수 있는 이름 목록이 생성된다고 가정합니다.

답변2

명령을 사용하여 이 작업을 수행 할 수 있습니다 xargs. 다음 파일이 있는 경우:

$ ls
A_file.txt  B_file.txt  C_file.txt  D_file.txt  E_file.txt  F_file.txt  G_file.txt  H_file.txt

그러면 다음과 같이 두 가지를 모두 처리할 수 있습니다.

$ find . -type f | xargs -n2 echo some_program
some_program ./A_file.txt ./B_file.txt
some_program ./C_file.txt ./D_file.txt
some_program ./E_file.txt ./F_file.txt
some_program ./G_file.txt ./H_file.txt

여기서는 단순히 이라고 부르지만 echo, 물론 포기 echo하고 실제로 실행할 수도 있습니다 some_program. 이는 한 번에 두 개의 파일을 처리하지만 각 호출에 대한 출력 파일 이름 생성을 처리하지 않습니다.

좀 더 자세하게 설명하면 첫 번째 입력 파일 이름을 따서 명명된 파일에 이를 출력할 수 있습니다.

find . -type f | xargs -n2 sh -c 'echo some_program $1 $2 > $1.output' --

A_file.txt.output그러면 및 , 다음 쌍 등에 A_file.txt대한 파일이 생성 됩니다 . 다양한 변환을 적용하여 출력 파일 이름을 선호할 수 있습니다. 예를 들어 질문에서 요청한 파일 이름을 얻으려면 다음과 같이 작성할 수 있습니다.B_file.txtC_File.txt.output

find . -type f | xargs -n2 sh -c 'echo some_program $1 $2 > output_${1:2:1}${2:2:1}' --

그러면 출력 파일 이름 등이 생성됩니다 output_AB.output_CD

답변3

bash에서 zsh로 전환할 수 있는 옵션이 있는 경우 다음을 수행하세요.

for i j ( *.txt(N) ) some_program -- $i $j > output_$i[1]$j[1]

(N)일치하는 항목이 없을 경우 오류가 보고되지 않도록 이 glob 확장에서 nullglob을 활성화합니다.

파일 수가 홀수이면 마지막 실행이 $j빈 문자열로 설정됩니다. 매개변수에 따옴표를 넣지 않으면 some_program해당 매개변수가 전달되지 않습니다. "$j"이 경우 빈 매개변수를 전달하려면 로 바꾸십시오.

확장자는 *.txt알파벳순으로 정렬됩니다. 를 사용하거나 o원하는 O대로 순서를 변경할 수 있습니다.n 글로벌 예선.

반복당 2개가 아닌 파일 수에 관계없이:

files=( *.txt(N) ) n=5
while (( $#files )) {
  some_program -- $files[1,n] > output_${(Mj[])files[1,n]#?}
  files[1,5]=()
}

또는 다음을 사용하십시오 zargs.

autoload -Uz zargs
process() some_program -- $@ > output_${(Mj[])@#?}
zargs -rl5 -- *.txt(N) -- process

에서는 배열의 각 요소에서 선행 문자가 제거되지만 에서는 추가된 ${(Mj[])array#?}내용 이 반환됩니다. 결과 는 없음( )이므로 각 요소의 첫 번째 문자로 구성된 문자열을 얻습니다.${array#?}MMj[]

답변4

파일 목록을 배열로 덤프하고 읽습니다.

#!/bin/bash
arr=( *.txt )
i=0
while [ $i -lt ${#arr[@]} ];
do
  echo ${arr[$i]} ${arr[ $[$i+1] ]}
  i=$[$i+2]
done

파일 수가 홀수인 경우 요청은 ${arr[ $[$i+1] ]}자동으로 빈 문자열을 제공합니다. 이 상황에서 무엇을 해야 할지는 당신에게 달려 있습니다.

관련 정보