각 디렉터리의 파일을 크기별로 정렬한 다음 디렉터리 형식(아래)을 유지하면서 가장 큰 파일 두 개를 다른 위치에 복사하는 루프를 만들려고 합니다.
folder/sample 1
.../s1.fastq.gz
.../s2.fastq.gz
.../s3.fastq.gz
.../s4.fastq.gz
folder/sample 2
.../s1.fastq.gz
.../s2.fastq.gz
.../s3.fastq.gz
.../s4.fastq.gz
저는 리눅스를 처음 접해서 어려움을 겪고 있습니다. 나는 시도했다:
#!/bin/bash
mkdir newfolder
for dir in folder/*
do
echo $dir
ls -S $dir/*.gz | head -n +2 | cp -T newfolder
done
그러나 다음과 같은 오류가 발생합니다.
cp: missing destination file operand after 'newfolder.'
복사 기능에 대용량 파일을 올바르게 공급하는 방법은 무엇입니까?
xargs도 사용해 보았지만 오류가 발생했습니다.
xargs: invalid option -- 'w'
한 번에 한 실씩 제대로 공급하지 않았기 때문입니다.
답변1
zsh
쉘의 경우 다음보다 더 나은 선택이 됩니다 bash
.
#! /bin/zsh -
ret=0
for dir (folder/*(/)) {
two_largest_files=($dir/*.gz(N.OL[1,2]))
if (($#two_largest_files)) {
mkdir -p newfolder/$dir:t &&
cp -v $two_largest_files newfolder/$dir:t/ || ret=$?
}
}
exit $ret
(모든 구현이 -v
verbose를 지원하는 것은 아닙니다. 구현이 이를 지원하지 않는 경우 대체하십시오.)cp
(set -x; cp $two...)
답변2
이것은 매우 복잡합니다. 첫째, ls
이름에 줄바꿈이 포함된 파일의 경우 상황이 복잡해질 수 있으므로 출력을 구문 분석해서는 안 됩니다 . 따라서 모든 파이프라인에서 레코드(줄) 구분 기호로 NUL을 사용하는 것이 좋습니다. 예는 다음과 같습니다.
for dir in folder/*
do
echo "$dir"
find "$dir" -type f -print0 -exec du -h0 {} + | sort -hrz | head -zn 2 |
sed -z 's/^.*[[:space:]]// ' | xargs -0I@ cp -v @ newfolder
done
find
주어진 파일을 찾으십시오"$dir"
. 여기에는 따옴표를 사용해야 합니다. 또한 모든 파일에서 작동하여du
크기를 얻습니다.sort
결과를 크기별로 정렬합니다.head
처음 2개로 제한됩니다.sed
파일 이름 앞의 크기 값을 제거하십시오.xargs
파이프라인의 매개변수를 사용하여 실제 명령을 빌드합니다.
NUL 구분 기호는 일반적으로 모든 명령에 표시되어야 하므로 , 및 ; z
플래그가 사용됩니다. 및의 스위치에 의해 생성됩니다.sort
head
sed
0
du
xargs
-print0
find
-T
(왜 에서 해당 플래그를 사용하는지 모르겠습니다 cp
. 제 예에서는 해당 플래그가 없지만 -v
피드백을 제공하기 위한 것입니다.)
답변3
코드에 두 가지 문제가 있습니다.
- 출력을 구문 분석하지 말고
ls
대신stat
다음을 사용하십시오. - 파일이 "많은" 경우 또는 파일 이름에 "흥미로운" 문자("
/sample 1/
") 가 포함된 경우find
및 를 사용합니다xargs
. 자세히 보고 알아man find
보세요man xargs
.
다음과 같이 하십시오:
mkdir newdir
find . -type f -name '*.gz' -print0 |\
xargs -0 -r stat --printf="%s:%N" |\
sort -rn |\
head -n 2 |\
cut -d: -f 2 |\
xargs cp -T newdir
경고하다! 테스트되지 않은 코드(전화를 걸고 있습니다). 마지막 줄을 다음으로 바꾸십시오.
xargs echo cp -T newdir
그것이 작동할 때까지.
궁금하신 분들은 한번 구경해 보세요https://mywiki.wooledge.org/ParsingLs