다음과 같은 스크립트를 만들려고 합니다.
- 이름에 "foobar"가 포함된 파일 찾기
- 스크립트는 이 파일에서 실행되며 출력은 자동으로 생성되고 검색된 파일과 이름이 동일한 새 CSV 파일에 저장되어야 합니다. 유일한 차이점은 확장자가 CSV로 변경된다는 것입니다.
이것은 내 스크립트입니다. :
#!/bin/bash
# search for file containing "foobar" as a name in the directory
for file in /home/user/Documents/* ;
do
if [[ "$file" == *"$foobar"* ]]; then
touch /home/user/Documents/collectCSV/csv1.csv
# executing script of modelising foobar file ==> extract some data from $foobar file and insert it in the
# created file csv1.csv
/home/user/scriptModelise.pl $file >> /home/user/Documents/collectCSV/csv1.csv
else
echo "foobar file not found"
fi
done
문제는 이 파일 생성 방법이 정적이라는 것입니다. 파일을 자동으로 생성하는 데 성공하지 못했습니다. 내 말은, foobar 파일을 찾으면 생성될 새 파일에서 이를 모델링한다는 뜻입니다.
도움이 필요하세요?
답변1
사용하기 더 쉽습니다(이와 같이 변수의 인용을 해제하면 zsh
이미 구문을 사용하고 있는 것입니다).zsh
#! /bin/zsh -
files=(/home/user/Documents/*foobar*(N))
if (($#files)) {
ret=0
for f ($files) {
/home/user/scriptModelise.pl $f > $f:h/collectCSV/$f:t:r.csv || ret=$?
}
exit $ret
} else {
echo >&2 No non-hidden foobar file
exit 1
}
csh
에서 와 마찬가지로 head(dirname), tail(basename), root(확장자 제거)$f:h
입니다 .$f:t
$f:r
((arithmetic expression))
ksh
평가 와 같은산술 표현0이 아닌 값으로 확인되면 true를 반환합니다.$#array
,ksh
s 를 연상시키는${#string}
배열의 길이를 제공합니다(요소 수로 표시).ksh
/ 에서bash
배열은 실제로는 별개의 유형이 아니므로${#array[@]}
인덱스 0${#array}
에 있는 요소의 길이(문자)가 필요합니다.(N)
: glob 한정자. 일치하는 항목이 없으면 비어 있는 상태로 확장됩니다.$f
,$files
: 다른 Bourne 유사 쉘과 달리 변수는 따옴표로 묶을 필요가 없습니다(널 값을 포함하지 않는 한). 다른 쉘(ksh, bash, yash)에서는"$f"
및 가 필요합니다"${files[@]}"
.
답변2
노력하다
for file in *"$foobar"*
do
dest="$(echo $file| sed -e 's/\(.*\)\.[^\.]*$/\1.csv/' )"
if test -f "$file"
then
/home/user/scriptModelise.pl "$file" >> /home/user/Documents/collectCSV/$dest
else
echo "no $foobar file"
fi
done
어디
\(.*\)\.[^\.]*$
임의의 문자(패턴 끝)와 점이 뒤따르고 줄 끝까지 점이 아닌 패턴을 캡처합니다.\1.csv
발견된 패턴 삽입, .csv 추가*"$foobar"*
*foobar*
일치하는 파일이 없으면 리터럴(올바른 값 포함)로 확장됩니다. 그러므로 필요하다test -f "$file"
편집하다:
\(.*\)\.[^\.]*$
(왼쪽: 찾기 모드)
( _ 는 자리표시자입니다)
__.*__________
임의의 문자가 포함된 패턴(점에는 특별한 의미가 있습니다: 임의의 문자)__.*__\._______
임의의 문자 뒤에 점이 있는 패턴(이스케이프 점은 일반 점입니다)__.*__\.[^\.]*$
줄 끝까지 임의의 문자(패턴 끝)와 점이 있고 점이 아닌([^\.]*
)이 있는 패턴(달러 기호는 줄 끝에 특별함)\(__\)__________
패턴의 첫 번째 부분을 캡처합니다.\1.csv
(오른쪽, 무엇을 해야할지)\1____
\1
\( \)
전체 패턴 에 대해 첫 번째, 두 번째 등\2
의 내용을 일치시킵니다.&
답변3
이는 GNU Parallel을 사용하면 쉽게 수행할 수 있으며, 보너스로 한 번에 여러 파일을 처리할 수도 있습니다.
parallel /home/user/scriptModelise.pl {} ">>" {.}.csv ::: *"$foobar"*
일치하는 파일이 없으면 오류가 발생하므로 *"$foobar"*
이를 먼저 확인하거나 find
이름을 파이프하거나 bash 옵션을 설정해야 합니다 failglob
.