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)

以下を使用してファイルツリー全体をコピーできますscprsync

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)

関連情報