다음 스크립트를 사용하면 사용자가 --header를 선택한 다음 file*을 파일 이름으로 삽입하여 모든 유효한 파일에 헤더를 추가할 수 있기를 원합니다.
#!/bin/bash
case "$1" in
--header )
for filename in "$@"
do
sed -i -e '1 e cat header' "$filename"
done
;;
--footer )
footer=~/dev/sed/footer
for filename in "$@"
do
cat "$footer" >> "$filename"
done
;;
esac
./tool --header file*을 실행하기 위해 도구를 실행하면 다음 오류가 발생합니다: sed: 인식할 수 없는 옵션 '--header'
$@ 변수가 첫 번째 변수 입력(--header)과 일치하려고 하기 때문에 이것이 발생한다는 것을 알고 있지만 이를 중지하는 방법을 모르겠습니다.
답변1
$@에서 첫 번째 요소를 제거하려면 를 사용합니다 shift
.
#!/bin/bash
opt=$1
shift
case "$opt" in
--header )
for filename in "$@" ; do
sed -i -e '1 e cat header' "$filename"
done
;;
--footer )
footer=~/dev/sed/footer
for filename in "$@" ; do
cat "$footer" >> "$filename"
done
;;
esac
답변2
문제는 루프(over)를 실행할 때 "$@"
옵션이 여전히 루프 중인 목록의 첫 번째 요소라는 것입니다. 반복하기 전에 $@
with 의 첫 번째 요소를 제거할 수 있습니다.shift
나는 명령줄 구문 분석과 조작을 분리하는 것을 선호합니다.
#!/bin/sh
unset do_header
unset do_footer
# loop until end of valid options...
while true; do
case $1 in
--header) do_header=1 ;;
--footer) do_footer=1 ;;
*) # assume end of options
break
esac
shift # we have processed a valid option, shift it off the list
done
# create a temporary file that we will use multiple times
tmpfile=$(mktemp)
# remove temporary file on normal exit (in bash, also on TERM/INT)
trap 'rm -f "$tmpfile"' EXIT
# For each file, copy it to the temporary file,
# then add header and footer as requested.
# Since we clobber the original file with the redirection,
# we won't be modifying permissions on the file.
# At this point, the valid options (any number of
# --header and --footer options) have been shifted off
# the list of arguments, so the $@ array now presumably only
# contains pathnames of files that are to be modified.
for pathname do
cp -- "$pathname" "$tmpfile"
cat ${do_header:+"header"} "$tmpfile" ${do_footer:+"footer"} >$pathname
done
또한 이를 통해 단일 호출로 머리글과 바닥글을 파일 세트에 추가할 수 있습니다.
변수가 설정되고 비어 있지 않은 경우 매개변수 대체가 ${var:+word}
확장됩니다.word
var
답변3
bash를 사용하는 경우 다른 옵션은 다음과 같습니다.
for filename in "${@:2}"
그러면 두 번째 인수부터 시작하여 인수가 제공됩니다. POSIX에서는 이를 지정하지 않으므로 일부 시스템에서는 이를 지원하지 않을 수 있습니다. 일부 쉘은 동일한 기능을 가지고 있지만 다른 구문을 사용할 수 있습니다.