HPC 클러스터를 사용하여 상당히 큰(~3GB) 파일 배치를 다운로드하기 위해 여러 개의 "wget" 셸 스크립트를 생성하고 싶습니다. 파일 이름은 다음과 같이 filenames.txt에 저장됩니다.
$cat filenames.txt
file1
file2
file3
...
내가 얻으려는 URL은 다음과 같이 구성됩니다.
ftp://host.com/dir1/dir2/file1/file1.sra
ftp://host.com/dir1/dir2/file2/file2.sra
ftp://host.com/dir1/dir2/file3/file3.sra
각 wget에 대한 쉘 스크립트를 생성하고 이를 변수 자체라는 파일에 쓰고 싶습니다. 예를 들어 file1.sh에는 다음이 포함되어야 합니다.
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
그리고 file2.sh에는 다음이 포함되어야 합니다.
#!/bin/bash
wget ftp://host.com/dir1/dir2/file2/file2.sra
보시다시피 일치하는 패턴은 1) URL과 2) 작성할 파일 이름입니다. 파일 이름에 URL을 "추가"한 다음 그 이름을 딴 .sh 파일에 쓰려면 어떻게 해야 합니까?
답변1
이를 수행하기 위해 매우 간단한 쉘 루프를 만들 수 있습니다.
while read filename
do
echo '#!/bin/bash' > $filename.sh
echo "wget ftp://host.com/dir1/dir2/$filename/$filename.sra" >> $filename.sh
done < filenames.txt
이는 각 줄을 읽고 filenames.txt
호출 한 다음, 각 줄에 대해 대체된 파일의 줄로 이름 이 지정된 filename
파일을 작성합니다 . 파일에는 두 줄이 있습니다: 각 파일에 , 원하는 명령(다시 파일 이름을 . 로 대체) 은 덮어쓰는 대신 동일한 파일에 두 번째 줄을 추가합니다. 이 스크립트를 실행한 후:$filename.sh
$filename
#!/bin/bash
wget
>>
$ cat file1.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
$ cat file2.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file2/file2.sra
루프 본문 내부에 세 번째 줄을 추가할 수 있습니다.
chmod a+x "$filename.sh"
이후에 스크립트를 실행 가능하게 만듭니다. 행 바로 위에 놓습니다 done
.
파일 이름에 공백이나 기타 특수 문자가 포함되어 있으면 여러 수준에서 문제가 발생하지만 영숫자 이름의 경우에는 잘 작동합니다.
답변2
다음 명령을 사용하십시오.
awk -v url='ftp://host.com/dir1/dir2' '{printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"}' filenames.txt
이 명령을 실행하면 아래와 같이 일련의 파일이 현재 디렉터리에 나타납니다.
$ ls *.sh
file1.sh file2.sh file3.sh
각 콘텐츠의 내용은 다음과 유사합니다.
$ cat file1.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
어떻게 작동하나요?
-v url='ftp://host.com/dir1/dir2'
이는 a를 변수
url
로 정의합니다.awk
printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"
그러면 필요한 모든 파일이 인쇄됩니다. 이
>$1".sh"
부분은 각 쉘 스크립트가 다운로드한 파일 이름을 따서 파일 이름을 작성하고.sh
확장자를 추가한다는 것을 의미합니다.
답변3
for
루프 printf
와 명령 대체를 사용하는 제안도 있습니다 $()
.
for file in $(<filenames); do
printf "%s\n%s\n" '#!/bin/bash' "wget ftp://host.com/dir1/dir2/${file}/${file}.sra" > "${file}.sh"
done
유일하게 중요한 부분은 아마도 $(<filename)
동일 $(cat filename)
하지만 조금 더 빠르다는 것입니다.