cp
배열을 사용하여 한 디렉터리에서 다른 디렉터리로 2개 이상의 파일을 복사하려고 합니다.
나는 다음을 실행했다:
files=(
LocalSettings.php
robots.txt
.htaccess
${domain}.png
googlec69e044fede13fdc.htm
)
파일 이름은 테이블을 사용하여 들여쓰기됩니다.
내 목표는 다음 이후에 실행하는 것입니다.
cp -a "source_path/${files[@]}" "/destanation_path"
내 문제는 변수 자체를 테스트할 때 전체 파일 목록이 아닌
echo $files
첫 번째 파일 이름만 반환된다는 것 입니다. 이것을 어떻게 설명하겠습니까?
관련된:LocalSettings.php
여러 줄 모드 cp;
답변1
그 Bash
기능은 다음과 같이 설명됩니다 man bash
.
첨자 없이 배열 변수를 참조하는 것은 첨자 0이 있는 배열을 참조하는 것과 같습니다.
files
배열의 모든 구성원을 인쇄하려면 다음을 수행하십시오 .
echo "${files[@]}"
다음 항목에도 설명되어 있습니다 man bash
.
${name[@]}은 이름의 각 요소를 별도의 단어로 확장합니다.
답변2
$files
목록(예: 질문에 있는 항목)인 경우에도 ${files[0]}
동일합니다 .files
목록의 첫 번째 요소 앞에만 "source_path/${files[@]}"
배치된다는 점에 유의하세요 . source_path/
각 요소 앞에 일부 경로가 붙는 방식으로 목록을 수정하려면 다음을 수행할 수 있습니다.
files=( ... your list of files ... )
for element in "${files[@]}"; do
files=( "${files[@]:1}" "source_path/$element" )
done
cp "${files[@]}" destanation_path
또는 실행 cd
전 실제 이름에 경로를 추가하거나 처음부터 목록에 값을 할당하면서 추가할 수 있습니다.source_path
cp
답변3
다른 사람들이 지적했듯이 $files
배열의 첫 번째 요소로만 확장되고 "source_path/${files[@]}"
첫 번째 요소에만 "source_path/"가 추가됩니다. 그러나 모든 요소를 가져오고 각 요소 앞에 경로를 추가하는 비교적 간단한 방법이 있습니다.
cp -a "${files[@]/#/source_path/}" "/destanation_path"
이는 [@]
전체 요소 확장( )과 교체를 결합합니다. /#
"문자열의 시작 부분에서 바꾸기", 바꿀 빈 문자열, /
구분된 바꾸기, 바꿀 항목(/add)으로 "source_path/"를 의미합니다. 이렇게 하면 각 요소에 소스 경로가 추가되며 일부 버전처럼 요소의 재미있는 문자로 인해 혼동되지 않습니다.
위의 예에서 "source_path/"는 끝에 슬래시가 있지만 시작 부분에는 슬래시가 없습니다. 앞의 "/"는 구분 기호입니다. 슬래시로 시작하고 "/source/path/"와 같이 더 많은 슬래시를 포함하는 경우에도 여전히 작동합니다.
cp -a "${files[@]/#//source/path/}" "/destanation_path"
답변4
다음 코드 조각을 사용해 볼 수도 있습니다.
IFS=$'\n'
cp -a $( printf "source_path/%s\n" "${files[@]}" ) /destination_path/
공백이 있는 파일 이름에도 작동합니다.