xargs를 사용하여 텍스트를 파일 배열로 복사

xargs를 사용하여 텍스트를 파일 배열로 복사

echo, xargs 및 cp를 사용하여 한 파일의 출력을 여러 파일에 복사하려고 합니다. 내 문제는 xargs가 배열의 첫 번째 파일에만 인쇄하고 3개 파일 모두의 복사본에는 인쇄하지 않는다는 것입니다. xargs를 잘못 사용하고 있거나 구문이 올바르지 않습니다. 나는 며칠 동안 이 작업을 해왔고 지금까지 여러 Google 페이지에서 운이 없었습니다. 어떤 도움이라도 대단히 감사하겠습니다!

#!/bin/bash

NF1=/home/user3/mynewfile
U3=/home/user3/
File=(grades mynewfile mynewfile1 mynewfile2)

mkdir -p /home/user3/{CIT/{tests/,grades/},MyStuff/{Tests/,Labs/},NOS/};
echo /etc/hosts.allow > $NF1;
echo $U3/CIT/tests/${File[*]} $U3/CIT/grades/${File[2]} | xargs -n 1 cp $NF1

답변1

구문과 관련이 있다고 의심되는 경우 다른 문제도 발견하여 사용을 완전히 버리고 루프를 xargs선호하는 버전을 생각해 냈습니다 for.

#!/bin/bash

U3=/home/user3/
NF1=/home/user3/mynewfile
File=(grades mynewfile mynewfile1 mynewfile2)

mkdir -p /home/user3/{CIT/{tests,grades},MyStuff/{Tests,Labs},NOS};

echo /etc/hosts.allow > $NF1;

for i in "${File[@]}"; do
    cp $NF1 $U3/$i
done

cp $NF1 $U3/CIT/grades/${File[2]}
  • mkdir불필요한 후행 슬래시를 제거하기 위해 행이 단순화되었으며 mkdir후행 슬래시 유무에 관계없이 디렉토리를 계속 활성화하므로 더 이상 입력이 필요하지 않습니다.

남은 변경 이유:

중복 슬래시

원본 코드 몇 줄을 먼저 테스트하는 경우:

$ U3=/home/user3/
$ File=(grades mynewfile mynewfile1 mynewfile2)
$ echo $U3/CIT/grades/${File[2]}
/home/user3//CIT/grades/mynewfile1

저장된 경로에는 $U3후행 슬래시가 설정되어 있고 $U3/CIT/grades/${File[2]}해당 줄 뒤에도 슬래시가 있어 $U3bash가 이를 로 확장하게 됩니다 . 이는 이중 슬래시가 예 를 들어 불평할 수 있는 것과 동일하지 않기 /home/user3//CIT/grades/mynewfile1때문에 문제가 됩니다 .///cpno such file or directory

따라서 단일 슬래시를 참조하는 경우 먼저 후행 슬래시 없이 /설정하는 것이 좋습니다 .$U3

$ U3=/home/user3
$ File=(grades mynewfile mynewfile1 mynewfile2)
$ echo $U3/CIT/tests/${File[2]}
/home/user3/CIT/tests/mynewfile1

이제 추가 슬래시 없이 올바른 경로가 생성됩니다.

잘못된 지원 확장

수정 후 다음 오류는 다음과 같습니다.

$ echo $U3/CIT/tests/${File[*]}
/home/user3/CIT/tests/grades mynewfile mynewfile1 mynewfile2

나는 당신이 쉼표를 사용한 중괄호 확장과 같은 일반적인 접두사를 File사용하여 배열의 파일 이름을 확장하려고 한다고 추측합니다 ./home/user3/CIT/tests

$ echo tweedle{dum,dee}
tweedledum tweedledee

이런 형태의 버팀대 확장에서는

  • 중괄호 {바로 앞이나 뒤 }또는 둘 다에 문자열을 올바르게 적용한 것입니다.
  • 그러나 word, 쉼표를 사용하여 다른 단어 등을 사용합니다.,
  • 하지만 당신은 을 넣었습니다 ${File[*]}. 배열 내용을 이런 식으로 처리하는 것을 본 적이 없습니다.

$U3대신, 동일한 공통 시작 단어 또는 문자열( )과 배열( )에 따라 다른 다른 부분으로 구성된 목록을 출력하려면 루프를 $File사용하는 것이 좋습니다 .for

$ for i in "${File[@]}"; do
> echo $U3/$i
> done

입력할 필요가 없으며 >bash는 줄 연속을 나타내기 위해 자동으로 제공합니다. 스크립트에서는 다음을 수행합니다.

for i in "${File[@]}"; do
    echo $U3/$i
done

결과는 언제나

/home/user3/grades
/home/user3/mynewfile
/home/user3/mynewfile1
/home/user3/mynewfile2
  • 에서 for i in "${File[@]}"; do따옴표( )와 플러스는 "루프가 배열의 각 파일 이름을 별도의 인수로 올바르게 이해하도록 하는 데 @중요합니다 .for$File

시험

최종 목표는 변수가 참조하는 단일 파일을 plus 배열 plus $NF1의 확장으로 정의된 여러 위치 에 복사하는 것입니다.$U3$File$U3/CIT/tests/${File[2]}

이 경우 가장 좋은 방법은 echo 및 실행하려는 명령을 사용하여 테스트하는 것입니다. cp따라서 set먼저 테스트를 수행해 보겠습니다.

$ NF1=/home/user3/mynewfile

그 다음에

$ for i in "${File[@]}"; do
> echo cp $NF1 $U3/$i
> done
cp /home/user3/mynewfile /home/user3/grades
cp /home/user3/mynewfile /home/user3/mynewfile
cp /home/user3/mynewfile /home/user3/mynewfile1
cp /home/user3/mynewfile /home/user3/mynewfile2

$U3/CIT/grades/${File[2]}또한, 잊지 않도록 복사하고 싶은 것 같으니 추가 행으로 추가하세요.

$ echo cp $NF1 $U3/CIT/grades/${File[2]}
cp /home/user3/mynewfile /home/user3/CIT/grades/mynewfile1
  • 이것은 모두 cp실행될 명령에 해당합니다.
  • xargs원본 코드와 유사한 방식으로 매개변수를 사용하도록 다시 작성할 수 있지만 실제로는 더 많은 입력이 필요하므로 이를 피합니다.

echo따라서 이 문서의 예제에 있는 항목을 삭제하여 코드의 최종 버전을 생성하세요.

답변2

내가 작성한 스크립트에 어떤 문제가 있는지 모르겠습니다. don_crissti가 지적했듯이 set -x스크립트로 사용된 두 번째 줄은 디버깅을 위한 좋은 시작점입니다. 문제가 무엇인지 한눈에 확인할 수 있을 만큼 xargs 및 배열 확장에 대해 충분히 알지 못합니다.

하지만, 간단한 해결 방법이 있습니다.이 문제를 해결하는 더 좋은 방법어쨌든: 을 사용하면 tee하나의 명령으로 여러 파일에 쓸 수 있으며 원하는 경우 파일 내용을 바꾸는 대신 텍스트를 추가할 수도 있습니다.

스크립트를 올바르게 읽었다면 원하는 내용은 다음과 같아야 합니다.

#!/bin/bash

NF1=/home/user3/mynewfile
U3=/home/user3/
File=(grades mynewfile mynewfile1 mynewfile2)

mkdir -p /home/user3/{CIT/{tests/,grades/},MyStuff/{Tests/,Labs/},NOS/};
cd ${U3}CIT/tests/
echo /etc/hosts.allow | tee ${File[*]} ${U3}CIT/grades/${File[2]} $NF1
cd -

cd편집: 배열 확장은 기본적으로 공백으로 구분되어 있으므로 현재 작업 디렉터리가 아닌 /home/user3/CIT/tests에 생성될 "mynewfile, mynewfile1, mynewfile2" 파일을 추가했습니다 . (물론 이 작업을 수행하는 더 깨끗한 방법이 있습니다.)

관련 정보