${ls ...}를 bash로 바꾸는 동안 오류가 발생했습니다.

${ls ...}를 bash로 바꾸는 동안 오류가 발생했습니다.

다음 오류가 발생합니다.

./assemblyDB.116.las
test.sh: line 9: ${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}: bad substitution

스크립트는 다음과 같습니다.

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   no=${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}
   echo $no
done

답변1

${ ... }(중괄호) 여러 개 표시매개변수 확장, 가장 간단한 방법은 변수의 값을 확장하는 것입니다. 코드의 중괄호 안에 있는 내용은 유효한 매개변수 이름이나 다른 확장이 아니므로 쉘이 불평합니다.

구문이 $( ... )(일반 대괄호)인 명령 대체를 원하는 것 같습니다.

또한 약간 불필요한 것 같습니다. 변수는 파일 이름으로 확장된 다음 ls전달 됩니다. 그냥 대신 사용해도 됩니다 .ls $filename | sed...lsecho "$filename" | sed ...

즉, 셸에서 직접 다음과 같이 수정할 수 있습니다.

no="${filename/assemblyDB.}"   # remove first match
no="${no/.las}"

또는 표준 연산자를 사용하세요.

no="${filename#assemblyDB.}"   # remove from start of string
no="${no%.las}"                # remove from end of string

이것을 실행하는 경우 정규식의 모든 문자를 일치시키도록 sed주의할 수 있으므로 백슬래시로 인용하는 것이 더 정확할 것입니다. 인스턴스에 두 가지 명령을 제공 .할 수도 있습니다 .sedsed -e 's/assemblyDB\.//' -e 's/\.las//'

그럼 for filename in $(find . -type f -name "assemblyDB.*.las"); do문제가 다 있는거네ls를 구문 분석하다주로 파일 이름의 공백과 와일드카드 때문에 문제가 발생합니다. ksh/Bash/zsh에서는 셸에서 전체 루프를 실행할 수 있습니다.

shopt -s globstar         # in Bash
for filename in **/assemblyDB.*.las; do
    ...

답변2

명령 대체(3행)

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   no=$(ls $filename | sed 's/assemblyDB.//' | sed 's/.las//')
   echo $no
done

ls이미 지적했듯이 이는 (3번째 줄, 아니오 ) 와 같습니다.

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   no=$(echo $filename | sed 's/assemblyDB.//' | sed 's/.las//')
   echo $no
done

또는 더 짧음(라인 4가 사라졌고 이제 직접 에코됨)

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   echo $filename | sed 's/assemblyDB.//' | sed 's/.las//'
done

sed 명령은 다음과 같이 단순화될 수 있습니다(라인 3).

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   echo $filename | sed 's/assemblyDB.//;s/.las//'
done

또는 sed를 사용하여 중간 부분을 추출합니다. (여전히 3번째 줄)

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   echo $filename | sed -r 's/.*assemblyDB.(.*).las/\1/'" 
done

이제 for-iterator 대신 find-iterator: (라인 1~3 및 4가 사라졌습니다)

find . -type f -name "assemblyDB.*.las" -printf "%f\n" -exec sh -c "
   echo {} | sed -r 's/.*assemblyDB.(.*).las/\1/'"  ";"

assemblyDB.11.las
11
assemblyDB.9.las
9
assemblyDB.10.las
10

파일 이름이 이 순서 또는 유사한 순서로 되어 있는 경우 다음도 작동할 수 있습니다.

for i in {8..12} ; do ls assemblyDB.$i.las && echo $i ; done 2>/dev/null

assemblyDB.9.las
9
assemblyDB.10.las
10
assemblyDB.11.las
11

(8과 12는 시퀀스에서 누락된 파일을 보여주기 위해 포함되었습니다).

답변3

${}백틱을 사용하는 대신 `[키보드의 Escape 아래에 있는 버튼을 누르세요. ]

관련 정보