cp と grep を使用する詳細な bash スクリプトは、ファイル名の空白と機能しません。

cp と grep を使用する詳細な bash スクリプトは、ファイル名の空白と機能しません。

私自身は決してこれを行いませんが、Windowsシステムを使用している人はファイル名にスペースを追加する必要があると主張しています。

私はこの詳細なコマンドを書いていて、空白のあるファイルを除いてうまくいきます。一重引用符、二重引用符、ティック、バックスラッシュでエスケープなど、すべてを試しました。

このコマンドは、コピーしたくないファイルのリストを除いて、特定のファイル拡張子を持つディレクトリ内のすべてのエントリをコピーする必要があります。残念ながら、これらのファイルの一部にはスペースが含まれています。これはコマンドです:

cp $(ls *.txt *.docx | grep --invert-match --fixed-strings \
-e not_this_one.txt \
-e not_this_one_either.docx \
-e "no not me.txt" \
-e "please leave me out as well.docx")  ./destination_directory/

これを行う方法についてのアイデアはありますか?

答え1

パラメータ拡張の代わりfindと使用:xargs$(...)

find *.txt *.docx \( \
      -name not_this_one.txt \
      -o -name not_this_one_either.docx \
      -o -name 'no not me.txt' \
      -o -name "please leave me out as well.docx" \
    \) -prune -o -print0 |
  xargs -0 cp -t /tmp/destination_directory

-pruneコピーしたくないコンテンツを除外するには、このオプションを使用します。

-print0パイプで接続するときにxargs -0スペースを含むファイル名を正しく処理するNUL終了ファイル名を生成するには、findコマンドを使用します。

最後に、ファイル名のリストをコマンドに追加できるように-t <target_directory>onオプションを使用します(そうでない場合は、ターゲットディレクトリが最後にある必要があるため、状況は少し複雑になります)。cpxargs-t


または以下を使用してくださいtar

tar -cf- \
    --exclude=not_this_one.txt \
    --exclude='not_this_one_either.docx' \
    --exclude='no not me.txt' \
    --exclude='please leave me out as well.docx' *.txt *.docx |
  tar -C /tmp/destination_directory -xf-

(もちろん除外パターンのリストをファイルに入れて使用することもできます--exclude-from。)

答え2

ls *.txt *.docxtruにパイプを送信すると、|シェルが作成されます。文字列ファイルが分離されていない場所。スペース(または改行)で区切ることができます。これは、スペース(または改行)でこれらの文字列を使用してファイル名を分割しようとする次のツールで混乱を招く可能性があります。

質問にbashでタグ付けしたので、globの拡張はシェルによって行われ、bashはGLOBIGNOREに提供されている特定のファイルモードを拒否することができるので、簡単に次のことができます*.txt*.docx

( GLOBIGNORE='not_this_one.txt:not_this_one_either.docx:no not me.txt:please leave me out as well.docx';
  echo \
  cp -t /tmp/destination_directory *.txt *.docx
)

これは(...)、サブシェルが閉じられた後にGLOBIGNORE設定が削除されるようにするために行われます。もちろん削除して進めてもいいですunset GLOBIGNORE。 Echoはコマンドの結果を表示するために使用されます。結果が満足な場合は、エコーを削除してください。

関連情報