이것은 bash 구문에 대한 정신적 훈련에 가깝습니다. 우리가 함께 해결할 수 있도록 이것을 퍼즐이라고 생각하도록 초대합니다. 또는 bash를 이해하기 위한 도전으로.
질문
예를 들어 내 폴더에는 3개의 파일이 있습니다 ./etc
.
./etc
foo.txt.example
bar.txt.example
hello world.txt.example
(예, 이 파일에는 공간이 있습니다)
위 파일을 기반으로 이러한 대상을 실행하기 위한 대상을 구축했습니다. 작동하는 작업은 다음과 같습니다.
make "etc/foo.txt"
make "etc/bar.txt"
make "etc/hello world.txt"
따라서 이론적으로는 모든 대상을 실행하기 위해 다음과 같은 명령을 작성할 수 있습니다.
make "etc/foo.txt" "etc/bar.txt" "etc/hello world.txt"
내 질문은 다음과 같습니다.모든 것을 검색하는 bash 스크립트를 작성할 수 있습니까? ./etc/*.txt.example
파일 이름과 위 명령을 구성하시겠습니까?
필요하다
- 대답은 bash 명령 형식이거나 Makefile 대상 정의 형식이어야 합니다.
- 대부분의 Linux 환경에서는 기본적으로 실행해야 합니다. 일반적이지 않은 패키지를 설치할 필요가 없습니다.
내가 시도한 것
Makefile에서 위의 모든 파일 이름을 얻는 방법을 찾았습니다.
txt:
for fn in "etc/*.txt.example"; do \
echo "etc/$$(basename -s ".example" "$$fn")"; \
done
이는 기본적으로 bash에서 실행하는 것을 의미합니다.
for fn in "etc/*.txt.example"; do \
echo "etc/$(basename -s ".example" "$fn")"; \
done
다음과 같은 출력을 제공합니다.
etc/foo.txt
etc/bar.txt
etc/hello world.txt
이 루프의 출력을 다른 명령의 입력으로 사용하면 해당 명령은 모든 공백을 인수의 구분 기호로 처리하는 것으로 보입니다. 그래서 이거:
make $(for fn in "etc/*.txt.example"; do \
echo "etc/$(basename -s ".example" "$fn")"; \
done)
실제로는 다음과 같습니다.
make "etc/foo.txt" "etc/bar.txt" "etc/hello" "world.txt"
루프의 출력을 공백을 올바르게 유지하는 인수로 변환하는 방법이 있습니까?
답변1
배열을 사용할 수 있습니다.
# Get all example files in an array
examples=(etc/*.example)
# Strip the .example suffix from every element of the array
make "${examples[@]%.example}"
또는 GNU find, sed 및 xargs가 있는 경우(즉, nul 구분 기호 지원):
find etc -iname '*.example' -print0 | sed -z 's/\.example$//' | xargs -0 make
답변2
널로 구분된 파일 이름 목록을 생성하고 다음을 make
통해 전달합니다 xargs
.
for name in /etc/*.txt.example; do
printf '%s\0' "${name%.example}"
done | xargs -0 make
답변3
먼저 샘플 파일을 만든 다음
set etc/*.tbl.example
N="shift $#"
for arg
do
$N; N=;
set X ${1+"$@"} "$(expr "$arg" '\(.*\).example')"; shift
done
# and then...
make ${1+"$@"}