나는 여기에 당황스럽게 반올림 대답을했지만, Denis의 대답 은 내가 가장 기본적인 것을 놓쳤다는 것을 나에게 상기시켰다. 그래서 원래 답변을 삭제했습니다. 아무도 이후하지만 말했다 이 매우 기본적인 것, 나는 그것의 가치는 여기에 넣어 생각합니다.
원래 질문은 "공백으로 구분 된 파일 이름 목록이있는 텍스트 파일이 있습니다. 파일을 하나의 대상 디렉토리에 복사하는 방법"입니다. 처음에는 파일에서 특정 방식으로 항목을 추출해야한다고 생각하기 때문에 까다 롭거나 복잡해 보일 수 있습니다. 그러나 쉘이 명령 행을 처리 할 때 가장 먼저하는 일은 인수 목록을 토큰으로 분리 하고 (아무도 말하지 않은 비트는) 별도의 토큰을 공백 으로 만드는 것 입니다. 개행은 또한 토큰을 분리하므로 개행으로 분리 된 목록을 사용하는 Doug Harris의 테스트 결과는 동일합니다. 즉, 쉘은 공백으로 구분 된 목록을 예상하고 이미 처리 할 수 있습니다.
따라서 여기서해야 할 일은 공백으로 구분 된 목록 (이미 가지고 있음)을 명령의 올바른 위치에 두는 것입니다. 당신의 명령은 이것에 약간의 변형입니다 :
cp file1 file2 file3...file# target
유일한 주름은 텍스트 파일에서 1부터 #까지의 파일 목록을 가져 오려는 것입니다.
Dennis가 그의 의견에서 지적했듯이 원래 시도 ( cp
cat list.txt new_folder
)는 이미 작동했을 것입니다. 왜? 내부 명령 cat list.txt
은 셸에서 먼저 처리되고으로 확장되기 file1 file2 file3...file#
때문에 셸은 명령의 해당 부분에서 정확히 예상하고 원하는 것입니다. 작동하지 않으면 (1) 오타가 있거나 (2) 파일 이름이 다소 이상했습니다 (공백 또는 기타 특이한 문자가 있음).
모든 Dennis의 답변이 작동하는 이유는 단순히 작업에 필요한 파일 목록을 제공 cp
하여 해당 목록을 전체 명령에 속하는 위치에 배치하기 때문입니다. 다시 말하지만 명령 자체는 다음과 같습니다.
cp list-of-files target_directory
이 버전에서이 모든 것이 어떻게 결합되는지 쉽게 알 수 있습니다.
cp $(<list.txt) new_folder
$()
쉘이 괄호 안에서 명령을 실행 한 다음 더 큰 행의 해당 지점에서 출력을 대체합니다. 그런 다음 쉘은 전체 라인을 실행합니다. 그건 그렇고, $()
당신이 이미 백틱으로하고있는 것의 더 현대적인 버전입니다 (`). 다음 : <
파일 리디렉션 연산자입니다. 쉘에 내용 list.txt
을 표준 입력 으로 덤프하도록 지시합니다 . $()
비트가 먼저 처리 되므로 다음 과 같은 단계가 수행됩니다.
cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
분명히 2 단계는 단순히 원하는 일반적인 cp
명령입니다.
나는이 (아마도 매우 죽은) 말을 많이 때리고 있다는 것을 알고 있지만 그만한 가치가 있다고 생각합니다. 쉘이 명령을 처리하는 방법을 정확하게 이해 하면 명령을 더 잘 작성하고 단순화 할 수 있습니다. 또한 문제가 숨어있을 가능성이있는 곳을 보여줍니다. 이 경우, 예를 들어, 첫 번째 질문은 재미있는 파일 이름이나 가능한 오타에 관한 것이 었습니다. 곡예가 필요하지 않았습니다.