2016-06-13 2 views
-2

의 파일 이름에서 변수 모티브를 추출, 쉼표 디렉토리에 파일 이름의 목록을 분리 명령을 공급 :I는 다음과 같이 파일이 들어있는 디렉토리가 라벨

1_reads.fastq 
2_reads.fastq 
89_reads.fastq 
42_reads.fastq 

나는 먹이를하고 싶습니다 쉼표는 파이썬 프로그램에서 명령이 파일 이름의 목록을 분리, 그래서 파이썬 명령의 입력이 좋아하는 것 :

program.py -i 1_reads.fastq,2_reads.fastq,89_reads.fastq,42_reads.fastq 

또한, 나는 라벨링에 대한 파일 이름에 숫자를 사용하고 싶습니다 함수는 python 명령 내에서 입력이 다음과 같이 표시되도록합니다.

program.py -i 1_reads.fastq,2_reads.fastq,89_reads.fastq,42_reads.fastq -t s1,s2,s89,s42 

파일 이름과 레이블 ID가 같은 순서로 중요합니다.

+1

의 사용에 대한 건강한 주석을 추가 할 수 나를 설득 찰스 더피에

감사합니다? "쉼표로 구분 된"은 정당한 이유로 표준 도구에서 사용되지 않습니다. (개행 문자로 구분 된 형식의 이름 목록을 허용하는 도구조차도 NUL으로 구분 된 스트림을보다 강력한 대안으로 허용합니다.) –

+0

질문을 이해했다면 "파일 이름 목록을 쉼표로 구분 된 목록으로 변환하는 방법은 무엇입니까? –

답변

2

이를 시도해보십시오 $ (..) 내부 테 명령 줄에서 반환 된 문자열을 program.py을 전달합니다

program.py $(cd DIR && var=$(ls) && echo $var | tr ' ' ',') 

.

그 명령 줄은 다음을 수행합니다. 디렉토리에 입력하고 ls를 변수에 저장하고 줄 바꿈 문자를 공백으로 대체하여 제거하며 후행 공백을 추가하지 않습니다. 그런 다음 변수를 'tr'에 에코하여 공백을 쉼표로 변환합니다.

+1

http://mywiki.wooledge.org/ParsingLs –

+1

'(cd"$ dir "&& names 만약 당신이 ** 정말로 ** 이것을 원한다면'(IFS = ','; {$ {names [*]};))'를 에코 할 필요가 없으며,'ls'에 대한 변명의 여지가 없습니다 .. –

+1

또한, 'echo $ var | ... '는 이름의 탭을 공백으로 변경하고, 이름의 glob를 다른 파일의리스트로 확장 할 것입니다. 확장을 인용하면 확장을 인용 할 필요가 있습니다. '는'-n'이라는 파일을 가지고 있다면 정의되지 않은 방식으로 동작합니다 –

2

첫 번째 : 이것은 매우 잘 고려되지 않은 호출 규칙입니다. 사용하지 마십시오.

  • IFS=, 사이에 쉼표를 넣어 ${array[*]} 원인 : 당신은 소프트웨어 누군가를 사용하는 경우이 어떻게 작동

    그러나, 다른 ... 이미 국제 대회에서 구운 것을

    #!/bin/bash 
    IFS=, # use comma as separator 
    
    files=([[:digit:]]*_*) 
    [[ -e $files || -L $files ]] || { echo "ERROR: No files matching glob exist" >&2; exit 1; } 
    
    prefixes=() 
    for file in "${files[@]}"; do 
        prefixes+=("s${file%%_*}") 
    done 
    
    # "exec" only if this is the last command in the script; remove otherwise 
    exec program.py -i "${files[*]}" -t "${prefixes[*]}" 
    

    을 썼다 각 확장 된 요소. 따라서 ${files[*]}${prefixes[*]}을 확장하면 각 배열의 내용과 함께 쉼표로 구분 된 문자열이 작성됩니다.

  • ${file%%_*}은 파일 이름에서 첫 번째 _ 다음의 모든 것을 제거하여 번호 만 추출 할 수있게합니다.
  • [[ -e $files || -L $files ]]은 실제로 해당 배열의 첫 번째 요소가 있는지 (symlink 또는 기타로) 테스트합니다. 그러나 파일을 두 줄의 호출 사이에 삭제하지 않는 한 배열을 형성하기 위해 확장 된 glob이 파일과 일치하면 항상 true가됩니다.
2

순수 배쉬에서는 쉽게 수행 할 수 있습니다. 파일이 들어있는 디렉토리에서 실행해야합니다.

#!/bin/bash 

shopt -s extglob nullglob 

# Create an array of files 
f=(+([[:digit:]])_reads.fastq) 

# Check that there are some files... 
if ((${#f[@]}==0)); then 
    echo "No files found. Exiting." 
    exit 
fi 

# Create an array of labels, directly from the array f: 

# Remove trailing _reads.fastq 
l=("${f[@]%_reads.fastq}") 
# And prepend the letter s 
l=("${l[@]/#/s}") 

# Now the arrays f and l are good: check them: 
declare -p f l 

# To join the arrays, we'll use eval. Safe because the code is single-quoted! 
IFS=, eval 'program.py -i "${f[*]}" -t "${l[*]}"' 

참고.eval의 사용은 우리가 상수 문자열을 전달할 때 완벽하게 안전합니다 (실제로 서브 셸이나 루프를 사용하지 않고 배열에 가입하는 관용적 방법). 명령, 특히 작은 따옴표는 수정하지 마십시오.당신이 그것을에서 쉼표로 이름이있는 경우 어떻게됩니까 eval

관련 문제