scp를 사용하여 디렉터리에서 특정 확장자를 가진 파일을 복사합니다.

scp를 사용하여 디렉터리에서 특정 확장자를 가진 파일을 복사합니다.

*_out.csv원격 서버의 디렉터리에서 모든 콘텐츠를 가져와야 하는 bash 스크립트를 작성 중입니다 . 이러한 파일은 모두 다른 디렉터리의 여러 디렉터리에 있습니다. 예를 들어, 디렉토리 이름이 이라고 가정해 보겠습니다 ox_20190404/. 다음을 사용하여 모든 파일을 찾을 수 있습니다.

find ox_20190404/assessment/LWR/validation -type f -name "*_out.csv"

이 질문은 내 질문의 일부에 대한 답변입니다., 하지만 디렉토리를 완전히 복사하고 싶지 않기 때문에 위 코드를 어떻게 구현해야 하는지 알아내야 합니다. 내가 이것부터 시작한다고 가정 해 봅시다 :

$ dir="/projects/ox/git"
$ server="myusername@server"
$ scp $server:$dir/$(ssh $server 'ls -t $dir | head -1') .

거기에서 필요한 파일을 어떻게 얻나요?

내 질문의 마지막 부분은 복사된 모든 파일을 가져와서 원격 서버의 동일한 파일 경로와 디렉터리에 배치할 수 있는 방법이 있는지 궁금합니다.

답변1

일부 변수 이름을 약간 수정했습니다.

확실히 이렇게 위험한 일보다 더 나은 방법이 있습니다ls의 출력을 구문 분석합니다., 그러나 이것이 귀하에게 적합한지 확인하십시오.

$ pth="/projects/ox/git"
$ server="myusername@server"
$ dir="$(ssh $server "ls -t \"$pth\" | head -1")"
$ mkdir -p "$pth/$dir"
$ scp -p $server:"$pth/$dir"/'*_out.csv' "$pth/$dir"/

dir최신 원격 디렉터리로 설정 되면 mkdir -p동일한 디렉터리 이름이 로컬에 존재하는지 확인하는 데 사용됩니다. 그런 다음 scp파일을 원격 디렉터리와 동일한 경로 및 이름을 가진 로컬 디렉터리에 복사합니다. rsync 솔루션을 찾고 있었지만 생각이 나지 않습니다.

답변2

\n디렉토리 이름에 개행 문자( ) 가 포함되어 있지 않다고 가정하면 가장 최근에 수정된(생성된) 디렉토리를 찾습니다.

newest=$(
    ssh -qn REMOTE 'find ./* -mindepth 0 -maxdepth 0 -type d -printf "%T@\t%f\n"' |
    sort -t$'\t' -r -nk1,2 |
    head -n1 |
    cut -f2-
)

대상에 관심 있는 디렉토리만 포함되어 있음을 보장할 수 있다면 이를 상당히 단순화할 수 있습니다(다시 한 번 개행 문제를 기억하세요).

newest=$(ssh -qn REMOTE ls -t | head -n1)

다음을 사용하여 전체 파일 트리를 복사할 수 있습니다 scp.rsync

rsync -av --include '*/' --include '*_out.csv' --exclude '*' --prune-empty-dirs REMOTE:"$newest" "$newest"

이전 파일 세트를 로컬에 유지하고 실제로 이전 파일 세트를 복사하지 않고 최신 파일 세트를 추가하려는 경우에도 rsync이 작업을 수행할 수 있습니다.

rsync -av --include '*/' --include '*_out.csv' --exclude '*' --prune-empty-dirs REMOTE: .

답변3

이것이 마침내 나를 위해 일한 코드입니다. 내 문제를 완벽하게 설명하지 못했을 수도 있지만 최근에 변경된 디렉토리를 찾는 데 아무런 문제가 없습니다. 내 문제는 해당 디렉터리에서 모든 파일을 찾아 내 로컬 컴퓨터의 올바른 위치에 있는지 확인하는 것입니다. 이를 수행하는 bash 스크립트는 다음과 같습니다.

# Grab the most recently updated ox file off of server; return as string
# in the form of ox_XXXXXXXX/assessment/LWR/validation/*
newest=$(
    ssh -qn username@server 'find /projects/ox/git/* -mindepth 0 -maxdepth 0 -type d -printf "%T@\t%f\n"' |
    sort -t$'\t' -r -nk1,2 |
    head -n1 |
    cut -f2- |
    awk '{print "/projects/ox/git/"$1"/assessment/LWR/validation/HBEP/analysis/BK363/*"}'
      )

# Take $newest and find all associated *_out.csv files beneath that directory
newestf=$(
    ssh -qn username@server "find $newest -type f -name '*_out.csv'"
    )

# Write these filepaths to a .csv on the local machine
echo "$newestf" | tr " " "\n" remote_fp.csv

# Run Rscript to parse and transform the filepaths so they go to the write place on local machine
Rscript ~/transform_fp.R

# Read content from .csv remote file paths - we'll need these to actually pull the files using scp
get_scp_fp=$(awk -F "\"*,\"*" '{print $1}' ~/remote_fp.csv)

# Read content from .csv local file paths - we'll need these to actually write the data locally
get_local_fp=$(awk -F "\"*,\"*" '{print $1}' ~/local_fp.csv)

# Loop through file paths and pull data from remote to local. 
for i in $get_scp_fp; do
    for j in $get_local_fp; do
    scp -p username@server:"$i" "$j"
    done
done

스크립트:

suppressPackageStartupMessages(library(tidyverse))

test <- read_csv("remote_fp.csv", col_names = FALSE)

str_replace_all(test$X1, "/projects/ox/git/ox_[0-9]{8}", "~/Documents/projects/ox") %>% 
  str_replace_all("(?:analysis).*$", paste0("doc/figures/", basename(.))) %>% 
  tibble() %>% 
  write_csv(path = "~/local_fp.csv", col_names = FALSE)

관련 정보