cp 명령의 출력으로만 파일 이름을 표시하는 방법은 무엇입니까?

cp 명령의 출력으로만 파일 이름을 표시하는 방법은 무엇입니까?

다음 명령을 사용하여 src 폴더에서 dest 폴더로 파일을 복사합니다.

cp -nv /src/* /dest/ > copy_result.txt

복사된 파일의 결과는 아래와 같이 출력 파일에 있습니다.

 « /src/test1.txt » -> « /dest/test1.txt »
 « /src/test2.txt » -> « /dest/test2.txt »

그렇지 않으면 출력 파일에 다음과 같이 전체 경로나 파일 확장자 없이 파일 이름만 포함되기를 원합니다.

test1
test2

답변1

명령을 시도해 보세요

cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

awk여섯 번째 필드를 인쇄합니다. 그리고 rev문자열을 반대로 바꿉니다. cut로 지정된 구분 기호에서 문자열을 분할하고 -d로 지정된 부분을 추출합니다 -f.

편집:
지적했듯이 공백이 있는 파일/디렉토리에는 적합하지 않습니다. 그러나 이는 '-> « '와 ' »' 사이의 하위 문자열을 추출하여 수행됩니다.

cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

답변2

-vPOSIX에 의해 지정되지 않았습니다. 이는 각 cp구현이 이를 다르게 처리할 수도 있고 전혀 처리하지 않을 수도 있음을 의미합니다. 당신이 cp말하는 곳에 « foo »나는 말한다 'foo'. 원하지 않는 출력을 원하는 출력으로 변환하는 명령을 작성하는 것이 가능하지만 여전히 구현과 독립적인 솔루션을 제시하고 싶습니다 cp.


/src/*명령이 확장된 후 cp결과 항목을 하나씩 복사합니다. 이는 당신이 cp -n /src/* /dest/다음과 같이 변할 수 있음을 의미합니다.

for file in /src/*; do cp -n "$file" /dest/; done

이제 를 사용하여 작업을 수행하는 것이 쉽습니다 $file. 그러면 원하는 출력이 생성됩니다.

for path in /src/*; do
   file="${path##*/}"
   dst="/dest/$file"
   [ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done

( 그냥 대신 copy_result.txt사용 하도록 리디렉션하려면 ).done > copy_result.txtdone


를 사용 cp -r -v하고 확장의 피연산자 중 적어도 하나가 /src/*디렉토리인 경우 cp해당 내용을 복사하고 인쇄하는 반면 위 코드( 를 추가한 후 -r)는 그만큼 복사하지만 디렉토리 자체만 인쇄합니다. -r불일치를 초래하는 유일한 옵션은 아닐 수도 있습니다.

따라서 접근 방식은 구현과 독립적이어야 하지만 cp사용되지 않는 일부 옵션에 의존합니다. 또 다른 단점은 코드가 의 cp모든 객체에 대해 별도의 프로세스를 실행한다는 것입니다 /src/. 이는 최적과는 거리가 멀습니다.

경쟁 조건도 있습니다. 파일이 과 $dst사이에 나타나면 해당 작업 을 수행합니다. 덮어쓰기를 방지하기 위해 를 사용할 수 있지만 여전히 파일을 보고합니다.[cpcpcp -nprintf

관련 정보