We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update I1022 to only suggest sub if all values can be in the sub
### CloudFormation Lint Version

0.64.1

### What operating system are you using?

All

### Describe the bug

Original feedback provided by @iann0036.  Translated to an issue for tracking.

```yaml
Fn::Join:
  - ""
  - - Fn::Select:
       - 0
       - Fn::Split:
          - "/"
          - !Ref MySubnet1CIDR
    - !Ref MySubnetsCIDRSize
```

```
I1022: Prefer using Fn::Sub over Fn::Join with an empty delimiter
```

### Expected behavior

Currently the way to make this comply would be

```yaml
Fn::Sub:
    - ${CIDR}${MySubnetsCIDRSize}
    - CIDR:
        Fn::Select:
          - 0
          - Fn::Split:
            - "/"
            - !Ref MySubnet1CIDR
```

which may not be as optimal 

### Reproduction template

```yaml
Fn::Join:
    - ""
    - - Fn::Select:
        - 0
        - Fn::Split:
          - "/"
          - !Ref MySubnet1CIDR
      - !Ref MySubnetsCIDRSize
 ````

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cfnlint/rules/functions/SubNotJoin.py`
Content:
```
1 """
2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 SPDX-License-Identifier: MIT-0
4 """
5 from cfnlint.rules import CloudFormationLintRule, RuleMatch
6 
7 
8 class SubNotJoin(CloudFormationLintRule):
9     """Check if Join is being used with no join characters"""
10     id = 'I1022'
11     shortdesc = 'Use Sub instead of Join'
12     description = 'Prefer a sub instead of Join when using a join delimiter that is empty'
13     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html'
14     tags = ['functions', 'sub', 'join']
15 
16     def match(self, cfn):
17         matches = []
18 
19         join_objs = cfn.search_deep_keys('Fn::Join')
20 
21         for join_obj in join_objs:
22             if isinstance(join_obj[-1], list):
23                 join_operator = join_obj[-1][0]
24                 if isinstance(join_operator, str):
25                     if join_operator == '':
26                         matches.append(RuleMatch(
27                             join_obj[0:-1], 'Prefer using Fn::Sub over Fn::Join with an empty delimiter'))
28         return matches
29
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cfnlint/rules/functions/SubNotJoin.py b/src/cfnlint/rules/functions/SubNotJoin.py
--- a/src/cfnlint/rules/functions/SubNotJoin.py
+++ b/src/cfnlint/rules/functions/SubNotJoin.py
@@ -7,12 +7,34 @@
 
 class SubNotJoin(CloudFormationLintRule):
     """Check if Join is being used with no join characters"""
+
     id = 'I1022'
     shortdesc = 'Use Sub instead of Join'
-    description = 'Prefer a sub instead of Join when using a join delimiter that is empty'
+    description = (
+        'Prefer a sub instead of Join when using a join delimiter that is empty'
+    )
     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html'
     tags = ['functions', 'sub', 'join']
 
+    def _check_element(self, element):
+        if isinstance(element, dict):
+            if len(element) == 1:
+                for key, value in element.items():
+                    if key in ['Fn::Sub']:
+                        if not isinstance(value, str):
+                            return False
+                    elif key not in ['Ref', 'Fn::GetAtt']:
+                        return False
+
+        return True
+
+    def _check_elements(self, elements):
+        for element in elements:
+            if not self._check_element(element):
+                return False
+
+        return True
+
     def match(self, cfn):
         matches = []
 
@@ -21,8 +43,15 @@
         for join_obj in join_objs:
             if isinstance(join_obj[-1], list):
                 join_operator = join_obj[-1][0]
+                join_elements = join_obj[-1][1]
                 if isinstance(join_operator, str):
                     if join_operator == '':
-                        matches.append(RuleMatch(
-                            join_obj[0:-1], 'Prefer using Fn::Sub over Fn::Join with an empty delimiter'))
+                        if isinstance(join_elements, list):
+                            if self._check_elements(join_elements):
+                                matches.append(
+                                    RuleMatch(
+                                        join_obj[0:-1],
+                                        'Prefer using Fn::Sub over Fn::Join with an empty delimiter',
+                                    )
+                                )
         return matches

{"golden_diff": "diff --git a/src/cfnlint/rules/functions/SubNotJoin.py b/src/cfnlint/rules/functions/SubNotJoin.py\n--- a/src/cfnlint/rules/functions/SubNotJoin.py\n+++ b/src/cfnlint/rules/functions/SubNotJoin.py\n@@ -7,12 +7,34 @@\n \n class SubNotJoin(CloudFormationLintRule):\n     \"\"\"Check if Join is being used with no join characters\"\"\"\n+\n     id = 'I1022'\n     shortdesc = 'Use Sub instead of Join'\n-    description = 'Prefer a sub instead of Join when using a join delimiter that is empty'\n+    description = (\n+        'Prefer a sub instead of Join when using a join delimiter that is empty'\n+    )\n     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html'\n     tags = ['functions', 'sub', 'join']\n \n+    def _check_element(self, element):\n+        if isinstance(element, dict):\n+            if len(element) == 1:\n+                for key, value in element.items():\n+                    if key in ['Fn::Sub']:\n+                        if not isinstance(value, str):\n+                            return False\n+                    elif key not in ['Ref', 'Fn::GetAtt']:\n+                        return False\n+\n+        return True\n+\n+    def _check_elements(self, elements):\n+        for element in elements:\n+            if not self._check_element(element):\n+                return False\n+\n+        return True\n+\n     def match(self, cfn):\n         matches = []\n \n@@ -21,8 +43,15 @@\n         for join_obj in join_objs:\n             if isinstance(join_obj[-1], list):\n                 join_operator = join_obj[-1][0]\n+                join_elements = join_obj[-1][1]\n                 if isinstance(join_operator, str):\n                     if join_operator == '':\n-                        matches.append(RuleMatch(\n-                            join_obj[0:-1], 'Prefer using Fn::Sub over Fn::Join with an empty delimiter'))\n+                        if isinstance(join_elements, list):\n+                            if self._check_elements(join_elements):\n+                                matches.append(\n+                                    RuleMatch(\n+                                        join_obj[0:-1],\n+                                        'Prefer using Fn::Sub over Fn::Join with an empty delimiter',\n+                                    )\n+                                )\n         return matches\n", "issue": "Update I1022 to only suggest sub if all values can be in the sub\n### CloudFormation Lint Version\n\n0.64.1\n\n### What operating system are you using?\n\nAll\n\n### Describe the bug\n\nOriginal feedback provided by @iann0036.  Translated to an issue for tracking.\r\n\r\n```yaml\r\nFn::Join:\r\n  - \"\"\r\n  - - Fn::Select:\r\n       - 0\r\n       - Fn::Split:\r\n          - \"/\"\r\n          - !Ref MySubnet1CIDR\r\n    - !Ref MySubnetsCIDRSize\r\n```\r\n\r\n```\r\nI1022: Prefer using Fn::Sub over Fn::Join with an empty delimiter\r\n```\n\n### Expected behavior\n\nCurrently the way to make this comply would be\r\n\r\n```yaml\r\nFn::Sub:\r\n    - ${CIDR}${MySubnetsCIDRSize}\r\n    - CIDR:\r\n        Fn::Select:\r\n          - 0\r\n          - Fn::Split:\r\n            - \"/\"\r\n            - !Ref MySubnet1CIDR\r\n```\r\n\r\nwhich may not be as optimal \n\n### Reproduction template\n\n```yaml\r\nFn::Join:\r\n    - \"\"\r\n    - - Fn::Select:\r\n        - 0\r\n        - Fn::Split:\r\n          - \"/\"\r\n          - !Ref MySubnet1CIDR\r\n      - !Ref MySubnetsCIDRSize\r\n ````\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass SubNotJoin(CloudFormationLintRule):\n    \"\"\"Check if Join is being used with no join characters\"\"\"\n    id = 'I1022'\n    shortdesc = 'Use Sub instead of Join'\n    description = 'Prefer a sub instead of Join when using a join delimiter that is empty'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html'\n    tags = ['functions', 'sub', 'join']\n\n    def match(self, cfn):\n        matches = []\n\n        join_objs = cfn.search_deep_keys('Fn::Join')\n\n        for join_obj in join_objs:\n            if isinstance(join_obj[-1], list):\n                join_operator = join_obj[-1][0]\n                if isinstance(join_operator, str):\n                    if join_operator == '':\n                        matches.append(RuleMatch(\n                            join_obj[0:-1], 'Prefer using Fn::Sub over Fn::Join with an empty delimiter'))\n        return matches\n", "path": "src/cfnlint/rules/functions/SubNotJoin.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass SubNotJoin(CloudFormationLintRule):\n    \"\"\"Check if Join is being used with no join characters\"\"\"\n\n    id = 'I1022'\n    shortdesc = 'Use Sub instead of Join'\n    description = (\n        'Prefer a sub instead of Join when using a join delimiter that is empty'\n    )\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html'\n    tags = ['functions', 'sub', 'join']\n\n    def _check_element(self, element):\n        if isinstance(element, dict):\n            if len(element) == 1:\n                for key, value in element.items():\n                    if key in ['Fn::Sub']:\n                        if not isinstance(value, str):\n                            return False\n                    elif key not in ['Ref', 'Fn::GetAtt']:\n                        return False\n\n        return True\n\n    def _check_elements(self, elements):\n        for element in elements:\n            if not self._check_element(element):\n                return False\n\n        return True\n\n    def match(self, cfn):\n        matches = []\n\n        join_objs = cfn.search_deep_keys('Fn::Join')\n\n        for join_obj in join_objs:\n            if isinstance(join_obj[-1], list):\n                join_operator = join_obj[-1][0]\n                join_elements = join_obj[-1][1]\n                if isinstance(join_operator, str):\n                    if join_operator == '':\n                        if isinstance(join_elements, list):\n                            if self._check_elements(join_elements):\n                                matches.append(\n                                    RuleMatch(\n                                        join_obj[0:-1],\n                                        'Prefer using Fn::Sub over Fn::Join with an empty delimiter',\n                                    )\n                                )\n        return matches\n", "path": "src/cfnlint/rules/functions/SubNotJoin.py"}]}