簡體   English   中英

cp 和 mv 中的 linux 通配符用法

[英]linux wildcard usage in cp and mv

我正在編寫一個腳本來處理 20 個文件。 它們都位於不同的目錄中。 我有部分文件名。

  1. 在日志目錄中,File1_Date_time.err 更改為 File1__Date_time_orig.err
  2. cd../腳本/
  3. sh文件.sh

File1目錄是/data/data1directory/Sample_File1/logs/File1_Data_time.err
File2目錄是/data/data2directory/Sample_File2/logs/File2_Data_time.err
.....

我的腳本看起來像這樣。 (runrunrun.sh)

#!/bin/bash
INPUT=$1
mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
sh /data/*/Sample_*/scripts/*_orig.sh

運行它時,我試過了。
./runrunrun.sh 文件1
. runrunrun.sh 文件1
sh runrunrun.sh File1

mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No such file or directory cp 也得到了類似的反饋

我做的對嗎?

謝謝!

讓我們先談談通配符的工作原理。

cp *.txt foo

如果存在與該 glob 匹配的任何文件,則實際上不會使用參數*.txt調用cp 相反,它運行如下:

cp a.txt b.txt c.txt foo

同樣,類似的東西

mv *.txt *.old

...不可能知道該怎么做,因為當它被調用時,它看到的是:

mv a.txt b.txt c.txt *.old

或者,更糟糕的是,如果您已經一個名為z.old的文件,它會看到:

mv a.txt b.txt c.txt z.old

因此,您需要使用不同的工具。 考慮:

# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
  mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done

# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
  cp "$f" "${f%.sh}_orig.sh"
done

# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
  if [[ -e "$f" ]]; then
    # honor the script's shebang and let it choose an interpreter to use
    "$f"
  else
    # script is not executable, assume POSIX sh (not bash, ksh, etc)
    sh "$f"
  fi
done

這使用參數擴展在添加新名稱之前去除舊名稱的尾端。

在您想要對通配符(或更復雜)文件名匹配執行操作的簡單情況下,可以非常簡潔地使用find命令。 下面的技術可以提交到內存......幾乎!

這是通過讓find命令在它找到的每個文件名上運行另一個命令來實現的。 您可以使用echo而不是 / 在mv前面空運行此示例。

如果我們想將當前目錄中名稱以“report”開頭的所有文件移動到另一個名為“reports”的並行目錄中:

find . -name "report*.*" -exec mv '{}' ../reports/ \;

通配符字符串必須用引號括起來,標記“找到”的文件名的 {} 必須用引號括起來,最后的分號必須轉義 - 所有這些都是由於 Bash/shell 對這些字符的處理。

看看man頁面find更多的用途: https://linux.die.net/man/1/find

這是我用的,寫起來很快,記起來也很快

對於復制:

ls -1 *.txt | xargs -L1 -I{} cp {} {}.old 

搬家:

ls -1 *.txt | xargs -L1 -I{} mv {} {}.old 

說明:

xargs(1) -L1 -I{}  

從標准輸入構建和執行命令行

-L max-lines
       Use  at most max-lines nonblank input lines per command line.  Trailing blanks cause an input line
       to be logically continued on the next input line.  Implies -x.

-I replace-str
       Replace occurrences of replace-str in the initial-arguments with names read from  standard  input.
       Also,  unquoted  blanks  do  not  terminate  input  items;  instead  the  separator is the newline
       character.  Implies -x and -L 1.

基本上使用-L1它將參數-L1發送,而-I{}使{}成為占位符

使用 awk 和 sed

使用 ls 過濾,使用 awk 為每條記錄構建移動命令,最后的 sed 'e' 將執行該命令。

ls  *.avro  | awk ' { print "mv "$1" aa_"$1 }' | sed 'e'

首先嘗試不使用 sed - 一旦您知道您的命令顯示正確,請添加 sed。

嘗試這個:

改變這些:

zc_cd_delim_01.csv
zc_cd_delim_04.csv

進入這些:

zc_cd_delim_113_01.csv
zc_cd_delim_113_04.csv

命令行:

for f in zc_cd_delim_??.csv; do var1=${f%%??.*}; 
    mv $f "${var1}113_${f#$var1}"; 
done

我正在編寫一個腳本來處理20個文件。 它們全部位於不同的目錄中。 我有部分文件名。

  1. 在日志目錄中,File1_Date_time.err更改為File1__Date_time_orig.err
  2. cd ../scripts/
  3. sh File.sh

File1目錄為/data/data1directory/Sample_File1/logs/File1_Data_time.err
File2目錄為/data/data2directory/Sample_File2/logs/File2_Data_time.err
.....

我的腳本看起來像這樣。 (runrunrun.sh)

#!/bin/bash
INPUT=$1
mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
sh /data/*/Sample_*/scripts/*_orig.sh

運行時,我嘗試過。
./runrunrun.sh File1
runrunrun.sh File1
sh runrunrun.sh File1

mv:無法移動/data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err :此類文件或目錄cp也沒有得到類似的反饋

我做對了嗎?

謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM