diff --git a/export_apkgs.py b/export_apkgs.py
index eaedd2e26159a9c507ea5f421fd01e021a14a4b6..e0d9b7bba54fae92af942e24c834d54073682765 100755
--- a/export_apkgs.py
+++ b/export_apkgs.py
@@ -42,6 +42,7 @@ class ImportApkg(BaseModel):
 
 class ImportCsv(BaseModel):
     content_version: datetime
+    delimiter: str
     note_type: str
     file_patterns: list[str]|None
     deck_name_pattern: str
@@ -109,6 +110,12 @@ class ApkgExporter:
     added_note_type_ids: list[int]
     added_card_types: set[str]
     resource_pseudo_usages: str
+    """
+    Note GUID against deck.
+
+    Set from the deck field in CSV.
+    """
+    note_deck_patterns: dict[str, str]
 
     def __init__(self, spec: ApkgSpec, content_dir: Path, intermediate_dir: Path, args: argparse.Namespace) -> None:
         self.spec = spec
@@ -121,6 +128,7 @@ class ApkgExporter:
         self.added_note_type_ids = []
         self.added_card_types = set()
         self.resource_pseudo_usages = ''
+        self.note_deck_patterns = {}
 
 
     def export(self) -> Path:
@@ -319,7 +327,6 @@ class ApkgExporter:
             if 'import_csv' in content:
                 import_csv : ImportCsv = content['import_csv']
                 deck_name = import_csv.deck_name_pattern
-                fields_mapping = import_csv.fields_mapping
                 ntid = name_to_ntid[import_csv.note_type]
                 with fake_time(format_time(import_csv.content_version)):
                     for pattern in import_csv.file_patterns or ['**/*.csv']:
@@ -330,8 +337,7 @@ class ApkgExporter:
                                 tmp_deck,
                                 import_csv.tags,
                                 csv_path,
-                                fields_mapping,
-                                import_csv.fields_static)
+                                import_csv)
                             self.move_to_target_decks(col, tmp_deck, deck_name, csv_path)
             elif 'import_apkg' in content:
                 import_apkg : ImportApkg = content['import_apkg']
@@ -377,23 +383,30 @@ class ApkgExporter:
             tmp_deck: int,
             tags: list[str],
             csv_path: Path,
-            fields_mapping: list[str],
-            fields_static: dict[str, str]):
+            opts: ImportCsv):
         with open(csv_path) as csv_file:
-            reader = csv.reader(csv_file, delimiter=';')
+            delimiter = opts.delimiter or "\t"
+            reader = csv.reader(csv_file, delimiter=delimiter)
             for row in reader:
-                note = Note(col, note_type_id)
-                note = self.new_note(col, row[fields_mapping.index('guid')], note_type_id)
-                for idx, field in enumerate(fields_mapping):
-                    if idx >= len(row):
-                        raise Exception(f'CSV row is missing {field} at index {idx}:\n{row}')
-                    if field != 'guid':
-                        note[field] = row[idx]
-                for field, value in fields_static.items():
-                    note[field] = value
-                for tag in tags:
-                    note.add_tag(tag)
-                col.add_note(note, tmp_deck)
+                # hash lines are comments
+                if len(row) >= 1 and not row[0].startswith('#'):
+                    note = Note(col, note_type_id)
+                    guid = row[opts.fields_mapping.index('guid')]
+                    note = self.new_note(col, guid, note_type_id)
+                    for idx, field in enumerate(opts.fields_mapping):
+                        if field != '':
+                            if idx >= len(row):
+                                raise Exception(f'CSV row is missing {field} at index {idx}:\n{row}')
+                            # deck overrides the pattern per note
+                            if field == 'deck':
+                                self.note_deck_patterns[guid] = row[idx]
+                            elif field != 'guid':
+                                note[field] = row[idx]
+                    for field, value in opts.fields_static.items():
+                        note[field] = value
+                    for tag in tags:
+                        note.add_tag(tag)
+                    col.add_note(note, tmp_deck)
 
     def field_columns(self, col: Collection, note_type_id: int, mapping: list[str]) -> list[int]:
         """
@@ -462,7 +475,9 @@ class ApkgExporter:
         for card_id in col.find_cards('deck:"' + TEMP_DECK_NAME + '"'):
             card = col.get_card(card_id)
             card_type_name = card.template()["name"]
-            desired_deck_name = self.format_deck_name(deck_name_pattern, csv_path, card_type_name)
+            guid = card.note().guid
+            pattern = self.note_deck_patterns[guid] if guid in self.note_deck_patterns else deck_name_pattern
+            desired_deck_name = self.format_deck_name(pattern, csv_path, card_type_name)
             card.did = self.get_or_create_deck_id(col, desired_deck_name)
             col.update_card(card)
 
diff --git a/test/fixtures/anki_text/.apkg-spec.yaml b/test/fixtures/anki_text/.apkg-spec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ead10a8a44b45bb2bd0a7475994c45d7e507b6ff
--- /dev/null
+++ b/test/fixtures/anki_text/.apkg-spec.yaml
@@ -0,0 +1,23 @@
+content_version: 1.0.0
+
+templates:
+- q_a
+
+content:
+- import_csv:
+    content_version: 2024-01-19 19:00:00+00:00
+    note_type: Q/A Testnotetype
+    file_patterns:
+    - '*.txt'
+    delimiter: "\t"
+    # Not needed because the CSV contains the deck name
+    deck_name_pattern: 'UNUSED'
+    fields_mapping:
+    - guid
+    - deck
+    - Question
+    - Answer
+    fields_static: {}
+    tags: []
+
+resource_paths: []
diff --git a/test/fixtures/anki_text/Tapirs.txt b/test/fixtures/anki_text/Tapirs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7b13e86517e847822f9d8bc899bfdeb3565b4686
--- /dev/null
+++ b/test/fixtures/anki_text/Tapirs.txt
@@ -0,0 +1,6 @@
+#separator:tab
+#html:true
+#guid column:1
+#deck column:1
+#tags column:4
+x,/Dh9c@Q^	Tapirs::Species	Which tapir has a prominent mane?	Tapirus terrestris	
diff --git a/test/fixtures/csv/.apkg-spec.yaml b/test/fixtures/csv/.apkg-spec.yaml
index 0c13501f9f75bfdac9f03ed50a5c173cabd31b30..5c2d69583643429d5e0bc38a840d042519140dc1 100644
--- a/test/fixtures/csv/.apkg-spec.yaml
+++ b/test/fixtures/csv/.apkg-spec.yaml
@@ -9,6 +9,7 @@ content:
     note_type: Q/A Testnotetype
     file_patterns:
     - '*.csv'
+    delimiter: ';'
     # and to making one deck per card type
     deck_name_pattern: '{{card_type}}'
     fields_mapping:
diff --git a/test/fixtures/csv_updated_content/.apkg-spec.yaml b/test/fixtures/csv_updated_content/.apkg-spec.yaml
index 18e0338dcde5da076c9971e9ccbc825d98d3e8aa..1e15dd28dcb6263c087e0676e2e50521800642e3 100644
--- a/test/fixtures/csv_updated_content/.apkg-spec.yaml
+++ b/test/fixtures/csv_updated_content/.apkg-spec.yaml
@@ -9,6 +9,7 @@ content:
     note_type: Q/A Testnotetype
     file_patterns:
     - '*.csv'
+    delimiter: ';'
     # and to making one deck per card type
     deck_name_pattern: '{{card_type}}'
     fields_mapping:
diff --git a/test/fixtures/fields_static/.apkg-spec.yaml b/test/fixtures/fields_static/.apkg-spec.yaml
index 455ae6ead9a0cea526bb6c353842df6a16ef2045..b4b47f81ac879e8bb85132c097564029ffa23b18 100644
--- a/test/fixtures/fields_static/.apkg-spec.yaml
+++ b/test/fixtures/fields_static/.apkg-spec.yaml
@@ -9,6 +9,7 @@ content:
     note_type: Q/A Testnotetype
     file_patterns:
     - '*.csv'
+    delimiter: ';'
     # and to making one deck per card type
     deck_name_pattern: '{{card_type}}'
     fields_mapping:
diff --git a/test/test_export_apkgs.py b/test/test_export_apkgs.py
index 7ff7af3471cfa0b9d8f5c7943633d843fcfa15d7..aeb5a365cec736cac6644164ebe4aa3169bbe0cd 100644
--- a/test/test_export_apkgs.py
+++ b/test/test_export_apkgs.py
@@ -17,6 +17,7 @@ CONTENT_PATH_ANKI = 'test/fixtures/anki'
 CONTENT_PATH_CSV = 'test/fixtures/csv'
 CONTENT_PATH_CSV_UPDATED_CONTENT = 'test/fixtures/csv_updated_content'
 CONTENT_PATH_FIELDS_STATIC = 'test/fixtures/fields_static'
+CONTENT_PATH_ANKI_TEXT = 'test/fixtures/anki_text'
 TEMPLATES_PATH = 'test/fixtures/templates'
 TEMPLATES_PATH_UPDATED = 'test/fixtures/templates_updated'
 
@@ -362,6 +363,48 @@ class TestExportApkgs(unittest.TestCase):
                 )
 
 
+    def test_anki_text(self):
+        """
+        Anki text export with deck name
+        """
+        with TemporaryDirectory() as temp_collection_dir:
+            col = Collection(str(Path(temp_collection_dir) / "test.anki2"))
+            with TemporaryDirectory() as first_export_dir:
+                args_first = MockArgs(
+                    content=CONTENT_PATH_ANKI_TEXT,
+                    templates_dir=TEMPLATES_PATH,
+                    output_dir=first_export_dir,
+                    dry_run=False)
+                package = export_package_from_spec(
+                    Path(CONTENT_PATH_ANKI_TEXT) / '.apkg-spec.yaml',
+                    args_first)
+
+                # import the first time, everything is new
+                result1 = col.import_anki_package(ImportAnkiPackageRequest(
+                    package_path=str(package),
+                    options=ImportAnkiPackageOptions(
+                        merge_notetypes=True,
+                        update_notes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER,
+                        update_notetypes=ImportAnkiPackageUpdateCondition.IMPORT_ANKI_PACKAGE_UPDATE_CONDITION_IF_NEWER,
+                        with_scheduling=False,
+                        with_deck_configs=False,
+                    )
+                ))
+                self.assertEqual(len(result1.log.new), 1)
+                self.assertEqual(
+                    result1.log.new[0].fields,
+                    # the empty one is resources
+                    [
+                        'Which tapir has a prominent mane?', 
+                        'Tapirus terrestris',
+                        ''
+                    ]
+                )
+                self.assertEqual(
+                    len(col.find_cards('deck:"Tapirs::Species"')),
+                    1)
+
+
 def find_template(col: Collection, name: str):
     template = None
     for name_and_id in col.models.all_names_and_ids():
diff --git a/version.txt b/version.txt
index 4a36342fcab700951adb18ae7adc930997f6c3f4..fcdb2e109f68cff5600955a73908885fe8599bb4 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-3.0.0
+4.0.0