z / xy以外のすべてのxyのファイルのリストを取得するには?

z / xy以外のすべてのxyのファイルのリストを取得するには?

Settings.jsonこのコンピュータには多くのファイルがあります。

私はこれらすべての人のリストを得るために次の方法を使います。

find / -name "Settings.json" 2>&-

しかし、そのいくつかはにありますApi。たとえば、次のようになります。

/ClubApi/Settings.json
/CrmApi/Settings.json

属していない限り、すべて削除したいと思います。Api...そうすることはできません。

私は試した:

find / -name "Settings.json" 2>&- | xargs grep -v Api 

ただし、パスフィルタリングには機能しませんApi

どうすればいいですか?

答え1

まず、このような習慣を持たないでください。閉鎖2>&-エラーを無視するには、標準エラーストリームを使用します。にリダイレクトする方が/dev/null安全です2>/dev/null。一部のコマンドは閉じたストリームに書き込みを試み、失敗すると終了します。

たとえば、参照してください。

{ echo 'error' >&2 && echo 'output'; } 2>&-

(何も出力しない)

{ echo 'error' >&2 && echo 'output'; } 2>/dev/null

(出力output)。


-path影響を与えないファイルを避けるためにテストを使用してください。

LC_ALL=C find / -type f ! -path '*Api/Settings.json' -name 'Settings.json' -print

または、*Api近くにいない場合は、次のディレクトリを完全に避けてください。

LC_ALL=C find / -name '*Api' -prune -o -type f -name 'Settings.json' -print

述語は-prune検索ツリーのブランチを「切り取り」(切り取り、削除)するため、上記のコマンドは名前が一致findするディレクトリには入りません*Api

-print-exec rm {} +実際にファイルを削除するには、上記のコマンドを変更してください。

答え2

削除操作を実行しているので、ファイルのリストを最初にテストするのが最善です。

find結果を改善するには、負のオプションを使用してください-not -path

find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json"  2>/dev/null

フィルタfind出力grep

find / -type f -name "Settings.json"  2>/dev/null | grep -v "[Aa]pi"

正しいリストを取得した後:

最も簡単な方法は、コマンドに-deleteタスクを追加することですfind

これは非常に危険運転中/

find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json" -delete 2>/dev/null

より慎重な削除コマンドrmは次のとおりです$(calculated list)

rm $(find / -type f (-not -path "*[Aa]pi*") -and -name "Settings.json"  2>/dev/null)

答え3

私は次の方法を使用してすべての人のリストを取得します。find …

findに頼るのではなく、シェルを使用してこれを行うこともできます。

#!/bin/bash
# To enable ** globbing
shopt -s globstar 

filename=Settings.json
for file in **/${filename} ; do
  if ! [[ "${file}" =~ Api/${filename}$ ]]; then
    # Do something, e.g. 
    # echo "${file}"
    # But beware! Files' and directories' names can contain newlines,
    # so I'd recommend either directly working on the file as you have it:
    # jq -r '.[0].command' < "${file}"
    # or printing it with the zero byte as terminator, instead of newline:
    # printf "%s\0", "${file}"
  fi
done

関連情報