Sao chép nhóm tệp (Tên tệp *) để sao lưu (Tên tệp * .bak)


13

Lý lịch

Trong Linux, bạn có thể:

  • Liệt kê một nhóm các tập tin với ls Filename*
  • Xóa một nhóm các tệp với rm Filename*
  • Di chuyển một nhóm các tập tin với mv Filename* /New/Directory
  • Nhưng bạn không thể sao chép một nhóm các tệp với:cp Filename* *.bak

Thay đổi Linux cp lệnh để sao chép nhóm tệp

Tôi có một nhóm các tệp tôi muốn sao chép mà không cần nhập từng tên một và sử dụng cplệnh:

$ ls gmail-meta3*
gmail-meta3                          gmail-meta3-REC-1558392194-26467821
gmail-meta3-LAB-1558392194-26467821  gmail-meta3-YAD-1558392194-26467821

Làm thế nào tôi có thể sử dụng một cái gì đó như lệnh DOS cũ copy gmail-meta3* *.bak ?

Tôi không muốn gõ lệnh tương tự bốn lần:

cp gmail-meta3-LAB-1558392194-26467821 gmail-meta3-LAB-1558392194-26467821.bak

Tôi đang tìm kiếm một tập lệnh / chức năng / ứng dụng chấp nhận các tham số cho nhóm tên tệp cũ và mới và không phải là một cái gì đó với tên tệp được mã hóa cứng. Ví dụ: người dùng có thể gõ:

copy gmail-meta3* *.bak

hoặc họ có thể gõ:

copy gmail-meta3* save-*

1
Vấn đề này đối với tôi khi sử dụng toán tử toàn cầu hai lần mà không có lệnh nào khác của bạn sử dụng. Bash không đủ thông minh để xử lý nó.
qwr

2
@qwr, thực tế là bash mở rộng các siêu ký tự và mã hóa đầu vào trước khi chuyển nó thành một lệnh được thực thi là một phần của thiết kế shell UNIX. Để bằng cách nào đó thử và lập trình một ngoại lệ cho lệnh cp sẽ phá vỡ toàn bộ tính nhất quán của bash, điều này sẽ không thông minh chút nào. Như một bài tập, hãy thử và tìm hiểu những gì đang xảy ra ở đây, và tại sao sự mở rộng metacharacter của vỏ làm cho nó trở nên như vậy:touch aa ab ba; mkdir bb; cp a* b*; ls *
Mike S

@MikeS Cảm ơn các con trỏ. Hôm qua có người khác nói bạn có thể sử dụng ký tự đại diện *cho tên tệp nguồn nhưng không phải cho tên tệp đích. Chẳng hạn như ký tự đại diện thay thế (tôi nghĩ ##đã được đề xuất nhưng tôi đang nghiêng về phía trước %) sẽ phải được sử dụng cho mục tiêu. Tôi nghĩ đây là những gì bạn đang củng cố? Tôi không mong đợi thay đổi cplệnh nào cả. Chỉ cần tạo một tập lệnh bao bọc được gọi là copymô phỏng (trong lý do) lệnh sao chép DOS.
WinEunuuchs2Unix

@ WinEunuuchs2Unix người đó đã đúng. Các siêu ký tự shell độc lập với các lệnh. Vì vậy, tất cả các ký tự đại diện sẽ cố gắng và phù hợp với tất cả các tệp phù hợp với mẫu. Nếu bạn đang cố gắng để thực hiện một mục đích chung "trận đấu tất cả mọi thứ và sao chép chúng vào bất cứ điều gì họ nhưng thêm hậu tố này" chương trình, sau đó có, chấm unescaped metacharater như là mục tiêu có thể sẽ không làm những gì bạn muốn. Bởi vì tất cả các siêu ký tự trong dòng lệnh shell được mở rộng. Nếu bạn BIẾT chắc chắn rằng metacharacter mục tiêu sẽ không bao giờ tạo thành một trận đấu, bạn có thể sử dụng nó - vì vỏ không thể mở rộng nó.
Mike S

... nhưng đó sẽ là một điều xấu xí để làm. Tốt hơn để sử dụng một nhân vật đặc biệt. % hoặc gạch dưới là tốt, nói chung họ không phải là siêu nhân vật (nhưng hãy cẩn thận khi sử dụng% trong tệp crontab; nó đặc biệt ở đó).
Mike S

Câu trả lời:


14

Dưới đây là một ví dụ về một cách sử dụng không điển hình sed, áp dụng cho nhiệm vụ này:

sed -i.bak '' file-prefix*

Theo cách này, thực tế, sedsẽ không thay đổi các tệp, vì chúng tôi không cung cấp bất kỳ lệnh nào '', nhưng do tùy chọn, -i[suffix]nó sẽ tạo một bản sao lưu của mỗi tệp. Tôi đã tìm thấy cách tiếp cận này khi tôi đang tìm kiếm Có cách nào để tạo bản sao dự phòng của một tệp mà không cần gõ tên của nó hai lần không?


FYI: $ time sed -i.bak '' gmail-meta3*=real 0m0.069s
WinEunuuchs2Unix

Nếu tập tin đã tồn tại thì : real 0m0.037s. Nếu các tệp bị xóa và chạy lần thứ hai gần với cptốc độ : real 0m0.051s.
WinEunuuchs2Unix

@xiota Một điểm thú vị. Hóa ra sedlà nhanh hơn khi các tệp mục tiêu đã tồn tại nhưng cpchậm hơn khi các tệp mục tiêu tồn tại. Tôi thực sự xóa bộ đệm và bộ đệm hơn là synckhi thực hiện các bài kiểm tra thời gian lớn nhưng lần này tôi không làm. Vì điều này có thể đi sâu vào một vở opera xà phòng ngoài chủ đề hoàn toàn khác, tôi rất tiếc khi chia sẻ kết quả kiểm tra của mình :( Có quá muộn để giả vờ cuộc trò chuyện này không bao giờ xảy ra không? Ngoài ra, đây không phải là ổ cứng, đó là ổ SSD Samsung Pro 960 NVMe trên 4 kênh.
WinEunuuchs2Unix

1
Có thể bạn không có vấn đề gì với thiết bị lưu trữ cho các thử nghiệm này, nếu điều này xảy ra trên máy Linux. Nhân cực kỳ tốt trong việc đệm các tệp trong bộ nhớ. Đó là giá trị "buff / cache" khi sử dụng freelệnh. Việc ghi thực tế vào thiết bị diễn ra tại một thời điểm được chọn bởi một thuật toán có tính đến tuổi của bộ đệm và áp suất bộ nhớ trên máy. Nếu bạn đang thử nhiều bài kiểm tra, thì lần đọc tệp đầu tiên sẽ thoát ra khỏi đĩa nhưng lần đọc tiếp theo rất có thể sẽ thoát ra khỏi bộ nhớ (xem sync; echo 3 > /proc/sys/vm/drop_caches).
Mike S

Hôm qua tôi đã thực hiện một vài thử nghiệm với các tệp lớn hơn 2GB và - vâng, cách tiếp cận này tương đối chậm so với sử dụng cplệnh, nhưng tôi không thể nói có bất kỳ sự khác biệt đáng kể nào về hiệu suất .
pa4080

13

Bạn có thể sử dụng find:

find . -max-depth 1 -name 'gmail-meta3*' -exec cp "{}" "{}.bak" \;

Điều đó sẽ tìm thấy trong thư mục hiện tại .tất cả các tệp có tên khớp với mẫu hình cầu (lưu ý các dấu ngoặc đơn xung quanh mẫu để ngăn chặn toàn cầu vỏ). Đối với mỗi tệp được tìm thấy, nó sẽ thực thi cptừ tên đến tên.bak. Các \; cuối cùng đảm bảo nó sẽ thực hiện từng tệp riêng lẻ thay vì chuyển tất cả chúng cùng một lúc. Độ sâu tối đa là 1 chỉ tìm kiếm thư mục cuurent thay vì đệ quy xuống.


1
Nó có hoạt động với find . -max-depth 1 -name '"$1"'' -exec cp "{}" "{}$2" \;khi $ 1 là nguồn và $ 2 là phần mở rộng không?
WinEunuuchs2Unix

$ 2 nên ok để thay thế miễn là hợp lý. $ 1 có thể phức tạp hơn vì chúng ta không thể thay thế trong các dấu ngoặc đơn. Tôi không chắc chắn nhưng có thể sử dụng $ 1 trong dấu ngoặc kép vì mẫu được lưu trữ trong một chuỗi.
cbojar

11

Bạn có thể sử dụng một forvòng lặp vớibash . Thông thường, tôi sẽ chỉ gõ nó dưới dạng một lớp vì đây không phải là nhiệm vụ tôi thường thực hiện:

for f in test* ; do cp -a "$f" "prefix-${f}.ext" ; done

Tuy nhiên, nếu bạn cần nó như một kịch bản:

cps() {
   [ $# -lt 2 ] && echo "Usage: cps REGEXP FILES..." && return 1

   PATTERN="$1" ; shift

   for file in "$@" ; do
      file_dirname=`dirname "$file"`
      file_name=`basename "$file"`
      file_newname=`echo "$file_name" | sed "$PATTERN"`

      if [[ -f "$file" ]] && [[ ! -e "${file_dirname}/${file_newname}" ]] ; then
         cp -a "$file" "${file_dirname}/${file_newname}"
      else
         echo "Error: $file -> ${file_dirname}/${file_newname}"
      fi
   done
}

Cách sử dụng tương tự như rename. Để kiểm tra:

pushd /tmp
mkdir tmp2
touch tmp2/test{001..100}     # create test files
ls tmp2
cps 's@^@prefix-@ ; s@$@.bak@' tmp2/test*    # create backups
cps 's@$@.bak@' tmp2/test*    # more backups ... will display errors
ls tmp2
\rm -r tmp2                   # cleanup
popd

FYI: $ time for f in gmail-meta3* ; do cp -a "$f" "${f}.bak" ; done=real 0m0.046s
WinEunuuchs2Unix

À không, tôi không muốn tối ưu hóa thời gian. Đó là 0.046giây có nghĩa là 0 giây đối với nhận thức của con người. Tôi chỉ cố gắng chỉ ra cách tôi đang kiểm tra các câu trả lời được đăng và chuyển các mẩu tin thú vị cho những người xem đã xem sedlệnh trên. Hoặc ít nhất tôi đã quan tâm đến việc so sánh sedvới cp....
WinEunuuchs2Unix

Giải pháp của bạn cplà nhanh hơn giải pháp sedmặc dù. Vì vậy, đó là một nguyên nhân cho lễ kỷ niệm :)
WinEunuuchs2Unix

(1)  -alà một toán tử thử nghiệm không chuẩn. Tại sao không sử dụng -e? (2) Không thể tạo thư mục tạm thời. là một thông báo lỗi hơi sai lệch. (3) Tại sao không chỉ sử dụng mktemp -d? (4) Bạn nên kiểm tra trạng thái thoát. Ví dụ, bạn nên nói ! mkdir "$FOLDER" && echo "Unable to create temporary directory." && return 1 hay  mkdir "$FOLDER" || { echo "Unable to create temporary directory."; return 1;}. Tương tự như vậy cho cpvà  rename(và có thể thậm chí pushd, nếu bạn muốn cẩn thận). Tiết (Cont'd)
G-Man nói 'Phục hồi Monica'

(Tiếp theo) Từ (5) Arrggghhhh! Đừng nói $@; tiếng nói "$@". (5b)  Không cần sử dụng {và } khi bạn tham chiếu các biến theo cách bạn đang làm ( "${FOLDER}",  "${PATTERN}" và  "${file}"); chỉ cần làm "$FOLDER",  "$PATTERN" và  "$file". (6) Điều này giả định rằng các tập tin nằm trong thư mục hiện tại.  cps 's/$/.bak/' d/foosẽ sao chép d/foođể foo.bak trong thư mục hiện hành, không d/foo.bak.
G-Man nói 'Phục hồi Monica'

6

Cách gần nhất bạn có thể sẽ đến mô hình DOS là mcp(từ mmvgói):

mcp 'gmail-meta3*' 'gmail-meta3#1.bak'

Nếu zshcó sẵn, zmvmô-đun đóng góp của nó có lẽ gần hơn một chút:

autoload -U zmv

zmv -C '(gmail-meta3*)' '$1.bak'

Tôi sẽ tránh lsbất kể - một biến thể trên câu trả lời của riêng bạn an toàn cho khoảng trắng (bao gồm cả dòng mới) sẽ là

printf '%s\0' gmail-meta3* | while IFS= read -r -d '' f; do cp -a -- "$f" "$f.bak"; done

hoặc có lẽ

printf '%s\0' gmail-meta3* | xargs -0 -I{} cp -a -- {} {}.bak

Tôi hiểu mmvlà gói nhưng trong các ý kiến ​​bạn nói lệnh là mcpnhưng sau đó trong lệnh bạn sử dụng mmvcũng là một lệnh trong mmvgói. Tôi thích hướng của các printfví dụ và trong một kịch bản được đánh bóng tôi đảm bảo $ 1 và $ 2 được thông qua. +1 để nhận bóng lăn :)
WinEunuuchs2Unix

@ WinEunuuchs2Unix xin lỗi - mcp / mmv là một trò chơi trí tuệ. Trên thực tế mcpchỉ là một từ đồng nghĩa vớimmv -c
Steeldo

Pfft không phải lo lắng. Nếu tôi có một đô la cho mỗi lỗi đánh máy, tôi đã trở thành triệu phú :) Tôi muốn làm rõ về printflệnh tôi chưa bao giờ thực sự sử dụng. Bạn đang nói printf '%s\0' "$1"*sẽ làm việc nếu gmail-meta3được thông qua như tham số 1?
WinEunuuchs2Unix

@ WinEunuuchs2Unix Có lẽ tôi sẽ để bối cảnh cuộc gọi thực hiện toàn cầu tức là cps gmail-meta3*viết printf '%s\0"$ @" | trong khi ... `trong hàm. Hoặc chỉ đơn giản là sử dụng for f; do cp -- "$f" "$f.bak"; done(như câu trả lời của xiota , nhưng là một chức năng)
Steeldo

1
Lưu ý rằng với zmvbạn có thể sử dụng chế độ "thay thế ký tự đại diện", điều này tôi thấy dễ hiểu hơn một chút:zmv -W -C 'gmail-meta3*' '*.bak'
0x5453

5

giải pháp chỉ rsync

Nếu bạn chỉ muốn sao lưu các tập tin của mình, bạn có thể sao chép chúng vào một thư mục mới

rsync /path/to/dir/Filename* /path/to/backupdirectory

Điều này sẽ sao chép các Filenametập tin từ /path/to/dir/đến /path/to/backupdirectory.


tên tập tin

Nếu bạn muốn các tệp sao lưu của mình có hậu tố, mọi thứ sẽ bị hack với rsync...

rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak

Điều này sẽ ghi đè lên các tệp hiện có ... với các tệp hiện có ( -I) nhưng chỉ khi chúng ( -u) mới hơn (không có) và tạo bản sao lưu, có hậu tố.

Bạn cũng có thể làm điều đó trong cùng một thư mục. Nhưng tốt hơn loại trừ các bản sao lưu hiện có.

rsync -Iu /path/to/dir/Filename* /path/to/dir/Filename* -b --backup-dir=/path/to/backupdirectory --suffix=.bak --exclude '*.bak'


Tôi yêu rsycncvì vậy tôi đã nâng cấp nhưng, một phương pháp đơn giản hơn là cp Filename* /path/to/backup/dirvì các tệp sẽ không cần đến trình *.bakduy nhất nếu chúng nằm trong một thư mục riêng.
WinEunuuchs2Unix

4

Điều này nên làm theo yêu cầu:

cps(){ p="${@: -1}"; for f in "${@:1:$#-1}"; do cp -ai "$f" "${p//\?/$f}"; done  }

Sử dụng:

cps FILES... pattern
Example 1: cps gmail-meta3* ?.bak
Example 2: cps * save-?
Example 3: cps * bla-?-blubb

Tôi đã chọn ?#phải được trích dẫn khi đó là ký tự đầu tiên của mẫu, nếu không, nó được công nhận là bắt đầu của một nhận xét.

Kiểm tra:

$ touch 'test};{bla#?"blubb'
$ cps test* bla-?-blubb
$ ls
test};{bla#?"blubb  bla-test};{bla#?"blubb-blubb


Một số phiên bản trước của tập lệnh để thêm hậu tố:

Tương tự như câu trả lời @ WinEunuuchs2Unix, nhưng tôi nghĩ linh hoạt hơn và không phân tích cú phápls :

cps(){ S="$1"; shift; printf '%s\0' "$@" | xargs -0 -I{} cp -abfS "$S" {} {}; }

Đặt cái này trong của bạn .bashrc.

Sử dụng:

cps SUFFIX FILES...
Example: cps .bak gmail-meta3*

Thay thế, với hậu tố là đối số cuối cùng ( thông quathông qua ):

cps(){ S="${@: -1}"; printf '%s\0' "${@:1:$#-1}" | xargs -0 -I{} cp -abfS "$S" {} {}; }

Sử dụng:

cps FILES... SUFFIX
Example: cps gmail-meta3* .bak


Mã hóa đẹp nhưng thật khó sau nhiều thập kỷ sử dụng Source rồi Target để chuyển lệnh sao chép sang Target rồi Source
WinEunuuchs2Unix

Đã thêm chức năng với hậu tố ở phía sau.
pLumo

Cảm ơn đó là trực quan hơn. Gọi nó là hậu tố là chính xác theo cách câu trả lời của tôi đã mã hóa nó nhưng nó thực sự là một mục tiêu hoặc đích đến. Những người dùng khác có thể muốn sử dụng : copy gmail-meta3* old-meta3*. Trong câu trả lời của tôi, tôi không thể tìm ra cách *vào tên đích như câu hỏi của tôi được yêu cầu ...
WinEunuuchs2Unix

vấn đề là *được giải thích bởi shell, vì vậy hàm sẽ không biết về nó. Bạn sẽ cần một số ký tự khác hoặc trích dẫn nó, sau đó thay thế nó bằng tên tệp gốc trong hàm.
pLumo

Tôi đoán #có thể được sử dụng như một ký tự đại diện thay thế cho *? Vì vậy, bạn có thể gõ copy filenames# save-#. Tôi nghĩ rằng bạn muốn ký tự đại diện giống nhau cho nguồn và đích.
WinEunuuchs2Unix

4

Tôi đã viết một trong những lót này vào của tôi ~/.bashrc. findTôi cho rằng câu trả lời tốt hơn nhiều có thể được đăng. Thậm chí câu trả lời tốt hơn có thể được viết bằng C. Hy vọng rằng câu hỏi và trả lời này sẽ giúp bạn có câu trả lời tốt hơn:

cps () {
    # cps "Copy Splat", copy group of files to backup, ie "cps Filename .bak"
    # Copies Filename1 to Filename1.bak, Filename2 to Filename2.bak, etc.
    # If Filename1.bak exists, don't copy it to Filename1.bak.bak
    for f in "$1"*; do [[ ! "$f" == *"$2" ]] && cp -a "$f" "$f$2"; done

    # OLD version comments suggested to remove 
    # ls "$1"* | while read varname; do cp -a "$varname" "$varname$2"; done
}
  • for f in "$1"*; do: $1gmail-meta3tham số và flà danh sách các tệp khớp. Kết hợp điều này có nghĩa là gmail-meta3, gmail-meta3-LAB-9999, v.v.
  • [[ ! "$f" == *"$2" ]] &&: $fgiống như ftrên. $2.baktham số được thông qua. Kết hợp điều này có nghĩa là nếu tên tệp không kết thúc .bak(vì chúng tôi không muốn sao chép .bakvà tạo .bak.bak) thì hãy làm như sau
  • cp -a "$f" "$f$2"; sao chép gmail-meta3 sang gmail-meta3.bak, v.v.
  • done: lặp lại và lấy tên tệp tiếp theo trong gmail-meta3danh sách *.

cps gmail-meta3 .bak Đầu ra mẫu

Sử dụng câu hỏi làm ví dụ ở đây là cách nó hoạt động:

───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/gmail$ ll gmail-meta3*
-rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3
-rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3.bak
-rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821
-rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821.bak
-rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821
-rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821.bak
-rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821
-rw-rw-r-- 1 rick rick   728954 Jun 27 05:46 gmail-meta3-YAD-1558392194-26467821.bak
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/gmail$ cps gmail-meta3 .bak
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/gmail$ ll gmail-meta3*
-rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3
-rw-rw-r-- 1 rick rick 26467821 May 20 16:43 gmail-meta3.bak
-rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821
-rw-rw-r-- 1 rick rick      643 May 20 16:43 gmail-meta3-LAB-1558392194-26467821.bak
-rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821
-rw-rw-r-- 1 rick rick    49607 May 20 16:44 gmail-meta3-REC-1558392194-26467821.bak
-rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821
-rw-rw-r-- 1 rick rick   728954 Jun 27 17:04 gmail-meta3-YAD-1558392194-26467821.bak
───────────────────────────────────────────────────────────────────────────────────────────
rick@alien:~/gmail$ 

Lưu ý: Điều này sử dụng -acờ với cplệnh để bảo toàn dấu thời gian và giúp bạn nắm bắt tốt hơn các bản sao lưu tệp của mình.

Lưu ý cách các bản sao tệp có cùng ngày giờ chính xác với bản gốc. Nếu -atham số bị bỏ qua, chúng sẽ được cung cấp ngày và giờ hiện tại và sẽ không giống như một bản sao lưu thực sự ngoại trừ kích thước tệp sẽ giống nhau.


6
không phải mọi người luôn khuyên bạn không nên phân tích cú phápls
qwr

3
Vì bạn đề cập đến findtôi cho rằng bạn nhận thức được sự nguy hiểm của việc phân tích cú pháp ls? Nhưng trong trường hợp của bạn thì không cần thiết: chỉ cần làm for file in "$1"*; do copy -a "$file" "$file$2"; done- điều này hoàn toàn an toàn và đơn giản hơn nhiều so với bất kỳ loại gián tiếp nào thông qua lshoặc findvà một whilevòng lặp.
Konrad Rudolph

@KonradRudolph Cảm ơn lời đề nghị của bạn. Tôi đã thực hiện và thử nghiệm đề xuất của bạn với một vài thay đổi nhỏ.
WinEunuuchs2Unix

2

Một phương pháp khác để đạt được yêu cầu của bạn là sao chép các tệp vào một thư mục tạm thời và sử dụng renamelệnh để đổi tên chúng.

$ mkdir backup
$ cp filename* /tmp/rename-backup/
$ rename 's/(filename.*)/$1.bak/' /tmp/rename-backup/*
$ mv /tmp/rename-backup/* ./

Nếu bạn cần nó như một kịch bản, bạn có thể sử dụng nó như vậy

cps () {
    mkdir -p /tmp/rename-backup/
    cp "$1"* /tmp/rename-backup/
    rename "s/($1.*)/\$1.$2/" /tmp/rename-backup/*
    mv "/tmp/rename-backup/$1"*".$2" .
}

Và bạn có thể sử dụng nó như vậy:

cps file bak

Đây là một ví dụ

$ ls -l
total 0
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file a
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ab
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ac
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename1
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename2
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename3
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename4
$ cps file bak
$ ls -l
total 0
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file a
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 file a.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ab
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 file ab.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:23 file ac
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 file ac.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename1
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename1.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename2
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename2.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename3
-rw-r--r--  1 danny  wheel  0 Jun 26 16:41 filename3.bak
-rw-r--r--  1 danny  danny  0 Jun 26 16:05 filename4
-rw-r--r--  1 danny  danny  0 Jun 26 16:41 filename4.bak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.