하위 디렉터리를 반복하고, 파일을 연결하고, 반복 번호를 사용해야 합니다.

하위 디렉터리를 반복하고, 파일을 연결하고, 반복 번호를 사용해야 합니다.

세 개의 다른 하위 디렉터리에 있는 파일을 하나의 파일로 연결하려고 합니다. 각 하위 디렉터리의 파일 이름은 정확히 동일합니다. 루프를 사용하여 하위 디렉터리를 반복한 다음 새 디렉터리의 새로 명명된 연결된 파일에 반복 번호를 입력하고 싶습니다. 예를 들어 디렉터리 구조는 다음과 같습니다.

Foo
|||
||Bar3
|Bar2
Bar1

각 Bar(?) 폴더에는 File1, File2, File3이라는 파일이 포함되어 있습니다.

같은 이름의 파일을 숫자가 포함된 새 이름의 더 큰 파일에 연결하고 싶습니다.

cat Foo/Bar1/File1 Foo/Bar2/File1 Foo/Bar3/File1 > /combined_files/all_file1

cat Foo/Bar1/File2 Foo/Bar2/File2 Foo/Bar3/File2 > /combined_files/all_file2

cat Foo/Bar1/File3 Foo/Bar2/File3 Foo/Bar3/File3 > /combined_files/all_file3

Foo내가 사용할 수 있는 디렉토리 에서 :

for number in {1..3}
    do
    cat Bar1/File$number\_* Bar2/File$number\_* Bar3/File$number\_* > combined_files/'all_files'$number
    done
exit

하지만 더 많은 수의 Bar 디렉터리와 파일에 대해서는 좀 더 일반적인 스크립트가 필요합니다. 나는 다음과 같은 것을 원한다

files=`ls ./Run1/ | wc -l`   #to count the number of files and assign a number
For n in {1..$files}
    do
    cat Bar1/File$n\_* Bar2/File$n\_* Bar3/File$n\_* > combined_files/'all_files'$n
    done

하지만 막혔어요.

답변1

#!/bin/sh

for pathname in Foo/Bar1/File*; do
    filename=${pathname##*/}
    cat "$pathname" \
        "Foo/Bar2/$filename" \
        "Foo/Bar3/$filename" >"combined/all_$filename"
done

이는 이름이 일치하는 모든 파일을 반복합니다 File*( Foo/Bar1패턴이 실제로 관심 있는 이름과 정확히 일치한다고 가정합니다).

이러한 각 파일에 대해 생성된 경로 이름의 파일 이름 부분을 추출합니다 (이 작업은 다음을 사용 $filename하여 수행할 수도 있음). filename=$(basename "$pathname")그런 다음 Foo/Bar2원본 파일을 및 디렉터리의 해당 파일과 연결하여 Foo/Bar3결과를 all_$filename다른 디렉터리의 새 파일에 씁니다.


일부 오류 확인 후:

#!/bin/sh

for pathname in Foo/Bar1/File*; do
    if [ ! -f "$pathname" ]; then
        printf '% is not a regular file, skipping\n' "$pathname" >&2
        continue
    fi

    filename=${pathname##*/}

    if [ -f "Foo/Bar2/$filename" ] &&
       [ -f "Foo/Bar3/$filename" ]
    then
        cat "$pathname" \
            "Foo/Bar2/$filename" \
            "Foo/Bar3/$filename" >"combined/all_$filename"
    else
        printf 'Missing %s or %s\n' "Foo/Bar2/$filename" "Foo/Bar3/$filename" >&2
    fi
done

하위 디렉토리 수가 다른 BarN변형 도 허용됩니다. 이것은추정BarN디렉토리에는 1부터 큰 숫자까지 번호가 매겨져 있습니다.

#!/bin/sh

# This is just used to count the number of BarN subdirectories.
# The number of these will be $#.
set -- Foo/Bar*/

for pathname in Foo/Bar1/File*; do
    filename=${pathname##*/}

    n=1
    while [ "$n" -le "$#" ]; do
        if [ ! -f "Foo/Bar$n/$filename" ]; then
            printf '%s missing, %s will be incomplete\n' \
                "Foo/Bar$n/$filename" "combined/all_$filename" >&2
            break
        fi

        cat "Foo/Bar$n/$filename"
        n=$(( n + 1 ))
    done >"combined/all_$filename"
done

답변2

@Kusalananda와 @Debian_yadav에게 다시 한 번 감사드립니다. 내 시스템에서 스크립트를 실행할 수 있습니다. 내 실제 디렉터리 이름은 다음과 같습니다.

Joes ||| ||Run3 |Run2 Run1

각 RunX 디렉터리에서 이름은 같지만 내용이 다른 파일을 만들었습니다.

실행1\파일1실행2
\파일1실행3
\파일1

먼저 보여드린 간단한 스크립트를 실행하고 디렉터리 구조를 약간 수정했습니다.

답변

#!/bin/bash
for pathname in Run1/File*; do
    filename=${pathname##*/}
    cat "$pathname" \
        "Run2/$filename" \
        "Run3/$filename" > "RunCat/all_$filename"
one

스크립트 출력은 다음 내용을 포함하는 "allFile1" 파일입니다. 123

귀하의 더 긴(최종) 스크립트(K2script.sh라는 이름)도 내 시스템에서 작동합니다.
디렉터리 구조를 약간 수정한 후에도 출력은 다시 정확히 동일합니다.

답변

#!/bin/sh
# This is just used to count the number of RunN subdirectories.
# The number of these will be $#.
set -- Joes/Run*/

for pathname in Run1/File*; do
    filename=${pathname##*/}

    n=1
    while [ "$n" -le "$#" ]; do
        if [ ! -f "Run$n/$filename" ]; then
            printf '%s missing, %s will be incomplete\n' \
                "Run$n/$filename" "RunCat/all_$filename" >&2
            break
        fi

        cat "Run$n/$filename"
        n=$(( n + 1 ))
    done >"RunCat/all_$filename"
done 

또는
또 다른 스택교환 토론

답변
폴더 이름을 변경하면 내 시스템에서 작동하게 되었습니다.

#!/bin/bash
for FILE in Run1/* ; do
    FILE2=Run2/${FILE#*/}
    FILE3=Run3/${FILE#*/}
    if [ -f $FILE2 ] ; then
        cat $FILE $FILE2 $FILE3 > RunCat/${FILE#*/}
    fi
done

while [ "$n" -le "$#" ]; do작동 방식 에 대해 많이 읽었 지만 다른 와일드카드나 정규 표현식이 작동하지 않는데 왜 작동하는지 ${pathname##*/}잘 이해할 수 없습니다 .${FILE#*/}

관련 정보