web-dev-qa-db-ja.com

cpおよびmvでのLinuxワイルドカードの使用

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ファイル1
。 runrunrun.shファイル1
sh runrunrun.shファイル1

mv:移動できません/data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err:そのようなファイルまたはディレクトリはありませんcpも同様のフィードバックを得ました

私はそれを正しくしていますか?

ありがとう!

10
TJ Wu

ワイルドカードがどのように機能するかについて話しましょう。

cp *.txt foo

そのグロブに一致するファイルが存在する場合、実際にはcpを引数*.txtで呼び出しません。代わりに、次のように実行します。

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

これは パラメータ展開 を使用して、新しい名前を追加する前に古い名前の末尾を削除します。

17
Charles Duffy

findコマンドは、ワイルドカード(またはより複雑な)ファイル名の一致に対して操作を実行する単純なケースで非常に簡潔に使用できます。以下のテクニックは、メモリにコミットすることができます...ほぼ!

これは、findコマンドに、見つかった各ファイル名に対して別のコマンドを実行させることで機能します。この例は、echoの代わりにmvを使用してドライランできます。

現在のディレクトリにある「report」で始まる名前のすべてのファイルを、「reports」という別の並列ディレクトリに移動したい場合は、次のようにします。

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

ワイルドカード文字列は引用符で囲む必要があり、「見つかった」ファイル名を示す{}は引用符で囲む必要があります。最後のセミコロンはエスケープする必要があります。これらはすべて、これらの文字のBash/Shell処理によるものです。

その他の用途については、findのmanページをご覧ください: https://linux.die.net/man/1/find

8
MikeW

これは私が使っているもので、非常に速く書いて覚えています

コピーの場合:

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引数を1つずつ送信し、-I{}{}プレースホルダー

0

これを試して:

これらを変更します。

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
0
Jon Lancelle