/bin/ls: 매개변수 목록이 너무 깁니다.

/bin/ls: 매개변수 목록이 너무 깁니다.

저는 autodock이라는 프로그램을 운영하는 생물학자입니다. ZINC 라이브러리에 .mol2 형식의 일부 파일이 있습니다. 요구 사항에 따라 명령을 사용하여 이 파일을 분할해야 하며 csplit디렉터리의 모든 콘텐츠를 받았습니다. 상위 파일은 여러 개의 작은 파일로 분할됩니다. 각 파일 이름은 다음과 같습니다. ZINC14382748.mol2이제 이 모든 파일을 pdbqt 형식으로 변경해야 하며 다음 스크립트를 사용해야 합니다.

#!/bin/csh # # $Id: ex02.csh,v 1.5 2007/07/19 21:52:59 rhuey Exp $ 
# 
# use the 'prepare_ligands.py' python script to create pdbq files 
cd $VSTROOT/VirtualScreening/Ligands 
foreach f (`ls *`) echo $f pythonsh ../../prepare_ligand4.py -l $f -d ../etc/ligand_dict.py end 

사용해보니 이렇게 나오네요

/bin/ls: Argument list too long

즉, 성공적으로 완료되면 위의 파일 수를 다른 형식으로 복사합니다. 그렇다면 이 문제를 해결할 합리적인 방법은 없을까요?

답변1

  1. 출력을 구문 분석하지 마십시오 ls.  말하다 foreach f (*). 반품,
  2. "$f"타당한 이유가 없고 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: )를 인용해야 합니다 .

답변2

문제의 근본 원인은 작은 파일이 너무 많다는 것입니다.

제가 착각한 것이 아니라면 14개 이상입니다.백만문서. 어떤 쉘도 명령줄에 1,400만 개가 넘는 파일 이름을 가질 수 없습니다. 게다가. 파일 이름의 길이는 약 18자이므로 파일 이름을 저장하는 데 약 18*14M 또는 약 252MB가 소요됩니다.

bash예를 들어 128KB 제한이 있습니다. 252MB보다 약간 작습니다. csh사용하지 않아서 어떤 제한이 있는지는 모르겠습니다 . bash의 명령줄 길이 제한보다 크지는 않습니다. 확실히 252MB 이상이 아닐 것입니다.

모든 것이 손실된 것은 아니지만 find ... -exec계속 사용할 수 있습니다.

find . -maxdepth 1 -type f -name '*.mol2' \
  -exec pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py \;

prepare_ligand4.py이는 각 파일에 대해 한 번씩 실행 되므로 다음이 필요합니다.매우장기. 대신 find ... -print0with xargs -0 -P ...또는 GNU를 사용하여parallel -0 ...find ... -exec


더 나은 해결책은 소스 코드를 다운로드 하고 이를 수정하여 큰 파일( -ing 전의 원본 파일 prepare_ligand4.py과 같은)을 제공할 수 있도록 하고 각 청크를 개별적으로 처리하는 것입니다. csplit이것은 ~이 될 것이다많은더 빠르고 쉽게 사용할 수 있습니다. 여전히 14M가 넘는 출력 파일이 있을 수 있지만(결합된 출력 파일이 쓸모없다고 가정하면...그렇지 않다면 운이 좋을 것입니다!) 14M 입력 파일과 14M 출력 파일을 갖는 것보다 낫습니다.

물론 이를 위해서는 약간의 python프로그래밍 기술이 필요합니다.

어쩌면 누군가가 이미 같은 문제에 직면하여 자신만의 향상된 버전을 작성했을 수도 있습니다 prepare_ligand4.py. 검색하는 데 시간을 투자하거나 시도해 볼 가치가 있습니다.오토독 포럼Autodock 작성자에게 문의해 보세요.

답변3

분명히 파일이 많이 있습니다. GNU Parallel 사용을 고려해보세요http://www.gnu.org/software/parallel/"ls -U"는 파일을 정렬하지 않으므로 속도가 더 빠릅니다.

cd $VSTROOT/VirtualScreening/Ligands
ls -U ZINC* | parallel echo {} \; pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py

왜 거기에 반응하는지 이해가 안 돼요. 새 스크립트로 구문 분석하시겠습니까? 내 생각에는 "prepare_ligand4.py"가 변환 스크립트인 것 같습니다. 그러면 이 작업이 병렬로 수행되어야 합니다.

cd $VSTROOT/VirtualScreening/Ligands
ls -U ZINC* | parallel pythonsh ../../prepare_ligand4.py -l {} -d ../etc/ligand_dict.py

답변4

이 문제를 해결하여 여러분과 공유합니다. bash.csh의 이름을 bash.sh로 바꾼 다음 bash에서 실행하도록 스크립트를 변경했습니다. 앞으로 동일한 문제를 해결하는 데 도움이 되는 새 스크립트는 다음과 같습니다.

#!/bin/bash
cd $VSTROOT/VirtualScreening/Ligands/
for f in ZINC*.mol2
do
    echo "$f"
    pythonsh ../../prepare_ligand4.py -l "$f" -d ../etc/ligand_dict.py
done

저와 같은 초보자의 경우 여기 ZINC는 모든 리간드 이름에 존재하는 이름의 일부이므로 리간드 이름에 따라 보존되어야 합니다. 시간을 내어 나를 도와준 열정과 친구에게 감사드립니다.

관련 정보