불특정 개수의 입력 값을 반복하여 각 입력 값에 대해 동일한 작업을 수행하는 스크립트를 작성하려고 합니다. 다음과 같은 파일 ~/bin/trash
:
#!/usr/bin/env bash
for f in "$@"
do
mv f ~/trashcan
done
저는 이렇게 사용하겠습니다
$touch 2.txt 3.txt 4.txt # create demo files
$trash *.txt
앞서 언급했듯이 Git Bash(Windows)에서 이 프로그램을 실행할 때 다음 오류가 발생합니다.
bash: syntax error near unexpected token `2.txt'
답변1
노력하다:
#!/usr/bin/env bash
for f; do
mv "$f" ~/trashcan
done
- '마킹은
$
필수입니다부르다선언된 변수($f
) for f in "$@"
여기서는 필요하지 않습니다
답변2
코드에서 루프 본문을 잊어버렸습니다 $
. 공백 등이 포함된 파일 이름을 지원 f
하려면 이 내용을 올바르게 인용해야 합니다 . "$f"
하지만 이것이 오류 메시지의 원인인지는 확실하지 않습니다(그리고 해당 오류를 발생시키는 코드가 아무것도 표시되지 않습니다). 내가 예상한 오류는 No such file or directory
존재하지 않는 항목을 이동하려는 것이 었습니다 f
.
이와 같은 작은 유틸리티의 경우 파일의 셸 함수로 변환할 수 있습니다 ~/.bashrc
.
trash () {
local trashcan="$HOME/trashcan"
mkdir -p "$trashcan"
mv -f -v "$@" "$trashcan"
}
이 기능은 콘텐츠를 휴지통 폴더로 이동하기 전에 실제로 존재하는지 확인합니다. 또한 이동되는 항목의 이름을 표시하면서 세부적으로 이동을 수행합니다.
"$@"
명령줄에서 함수에 지정된 이름으로 올바르게 확장되므로 여기서 반복할 필요가 없습니다 .
실제 반복 이름을 원하는 유일한 이유는 이동을 수행하기 전에 대상이 존재하지 않는지 확인하려는 경우입니다 mv
(새 항목이 휴지통의 내용을 덮어쓰지 않도록). GNU coreutils를 사용하면 mv
다음과 같은 방법으로 이를 자동화할 수 있습니다.
mv -f -v --backup=numbered "$@" "$trashcan"
GNU가 아닌 경우 mv
다음 루프가 필요할 수 있습니다(이 루프는 mv
위의 셸 함수에 있는 루프를 대체합니다).
local trash_ext="$RANDOM"
for name; do
while [ -e "$trashcan/${name##*/}.$trash_ext" ]; do
trash_ext="$RANDOM"
done
mv -f -v "$name" "$trashcan/${name##*/}.$trash_ext"
done
이는 파일 이름 뒤에 임의의 숫자를 추가하여 고유한 이름을 만드는 빠르고 더러운 방법입니다. 해당 ${name##*/}
항목은 기본 이름(경로 이름의 파일 이름 부분)으로 확장 $name
되며 $( basename "$name" )
.