다음 오류가 발생합니다.
./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...
ls
echo "$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
주의할 수 있으므로 백슬래시로 인용하는 것이 더 정확할 것입니다. 인스턴스에 두 가지 명령을 제공 .
할 수도 있습니다 .sed
sed -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 아래에 있는 버튼을 누르세요. ]