글쎄, 상황은 모두 동일한 이름의 프로필을 따르는 알 수 없는 수의 하위 디렉터리가 있다는 것입니다.
폴더 0, 폴더 1, 폴더 2, 폴더 3 등
이제 각 폴더에는 3개의 텍스트 파일이 있으며 이러한 텍스트 파일은 모든 폴더에서 동일한 3개의 파일 이름을 갖습니다.
파일 1 파일 2 파일 3
모든 폴더의 모든 텍스트 파일을 폴더 0, 파일 1, 파일 2, 파일 3부터 시작하여 모든 폴더에서 동일한 순서로 하나의 텍스트 파일로 연결하는 간단한 방법을 찾고 싶습니다.
이제 소수의 폴더에 대해 cat을 사용할 수 있습니다.
cat folder0/file1 folder0/file2 folder0/file3 folder1/file1 folder1/file2 folder1/file3 folder2/file1 folder2/file2 folder2/file3 folder3/file1 folder3/file2 folder3/file3 > textfile
하지만 폴더 수는 알 수 없습니다. 아마도 100개 또는 1000개일 것입니다.
이 작업을 수행할 수 있는 스크립트를 아는 사람이 있습니다.
답변1
Unix 도구와 파이프만 사용:
find ./ -type f -regex './folder[0-9]+/file[0-9]+' -print0 | sort -zV | xargs --null cat
설명하다:
find
특정 기준과 일치하는 모든 파일 검색
./
find
현재 위치(즉, 작업 디렉터리)에서 검색하라고 지시합니다 .-type f
find
file이라는 디렉터리가 있는 경우에만 파일을 찾도록 지시합니다.-regex
find
전체 경로가 주어진 패턴과 일치하는 파일만 검색함을 나타냅니다 . 이 경우 "./folder" 뒤에는 하나 이상의 숫자, 새 디렉터리, "file", 하나 이상의 숫자가 옵니다.-print0
출력에 널 문자로 구분된 파일을 찾도록 지시합니다find
. 이는 파일 이름에 나타나지 않는 것이 보장되며 파일 이름에 개행 문자가 포함되어 있어도 작동합니다.
sort
가져온 목록을 정렬합니다.
- 기본값인 개행 구분 항목 대신 널 문자 구분 항목을
-z
정렬 하도록 지시합니다.sort
- 인간이 직관적으로 항목을 정렬하는 것처럼 항목을 정렬하도록 지시합니다
-V
. 즉, 중간이 아닌 이후에 항목 을 정렬합니다.sort
file11
file1
file2
xargs
가져온 항목을 사용하여 에 인수로 전달하면 cat
짐작할 수 --null
있듯이 xargs
서로 다른 항목은 공백이나 개행 문자가 아닌 null 문자로 구분됩니다.
답변2
그리고 zsh
:
autoload zargs
zargs -r -- folder<->/file<1-3>(nN) -- cat > hugefile
bash
, 및 GNU 도구 사용 :
shopt -s extglob nullglob
print0() { (( $# == 0 )) || printf '%s\0' "$@"; }
xargs -r0a <(
print0 folder+([0123456789])/file[123] | sort -zV
) cat > hugefile
그중에는 +([0123456789])
( extglob
를 포함하여 ksh의 고급 glob 연산자 중 일부를 활성화함 +(...)
) zsh <->
(ASCII 10진수 시퀀스)에 해당하는 것, sort -V
zsh의 n
glob 한정자에 해당하는 GNU( 와 사이가 아닌 folder10
뒤에 오도록 숫자를 정렬하는 데 사용됨 ), glob 한정자 의 경우 zsh 대신 GNU를 사용하여 목록을 분할합니다.folder9
folder1
folder2
nullglob
N
xargs
zargs
인수 목록이 너무 깁니다.실수.
우리는 print0
인수를 NUL로 구분하여 인쇄하는 함수를 정의했습니다(bash에는 's가 없기 때문 zsh
). 그러나 여기서는 파일 경로에 print -rNC1
고유한 문자가 포함되지 않는다는 점을 고려하여 줄 바꿈으로 구분하여 인쇄하고 무시하는 것이 좋습니다. 사실: 목록이 비어 있으면 해당 줄은 무시되기 때문에 빈 줄을 인쇄합니다.xargs
-0
printf '%s\n'
xargs
답변3
특정 폴더 수에 도달하면 다음을 수행할 수 있습니다.
cat folder*/* > file
또는 특정 파일/디렉토리에 대해서만:
cat {folder1,folder2,folder3}/{file1,file2,file3} > file
이름이 고정 문자열과 연속 숫자로 구성된 경우 다음과 같이 더 단순화할 수 있습니다.
cat folder{1..3}/file{1..3} > file
이제 파일과 폴더가 많으면 이 작업이 실패하지만 대부분의 경우에는 작동합니다. 예를 들어 내 컴퓨터에서 다음 명령을 사용하여 1000개의 디렉터리에 3000개의 파일을 만들었습니다.
mkdir folder{1..1000}
touch folder{1..1000}/file{1..3}
for f in */*; do echo "$f" > $f; done
그런 다음 모든 파일을 하나로 연결합니다.
cat folder*/* > file
이는 3000줄을 포함하는 파일을 제공합니다.
그러나 문제가 발생하면 언제든지 다음을 사용할 수 있습니다 find
.
find folder1 folder2 folder3 -name "file[123]" -exec cat {} + > file
또는
find folder* -name "file[123]" -exec cat {} + > file
경고하다: 이러한 방법 중 어느 것도 순서를 지정할 수는 없지만 모든 디렉터리에서 동일한 순서를 가져야 합니다.