批处理 for参数之token详解

本文介绍Windows批处理中使用FOR /F命令进行列提取的方法,包括分隔符定义、特定列选择及范围提取等高级应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tokens=x,y,m-n 提取列

格式:

FOR /F "tokens=x,y,m-n" %%I       IN (Command1)   DO Command2

用法:

一句话总结:提取列。

通俗讲,共同提取每一行的第m小节的内容。

因此,可以用该命令来指定提取文本信息。

tokens=有时表示提取全部。

tokens=m表示提取第m列。

tokens=m,n表示提取第m列和第n列。

tokens=m-n表示提取第m列至第n列。

Tokens=*表示删除每行前面的空格。忽略行首的所有空格。

tokens=m*提取第m列以后的所有字符,星号表示剩余的字符。

tokens=m,*提取第m列以后的所有字符,星号表示剩余的字符。

输出变量的个数由定义了的tokens决定。

在 FOR 语句中显式声明 %%i。使用tokens= 隐式声明%%j 和%%k。只要不会引起试图声明高于字母“z”或“Z”的某个变量,则使用tokens= 可以指定最多 26 个输出变量。

接着前面的例子“静夜思”。

如果我要提取第三小节“举头望明月”,如何做到?

@echo off

for /f   "delims=, tokens=3"   %%i in (静夜思.txt) do echo %%i 

pause>nul

讲解:

首先用delims=,表示命令要用逗号作为诗句的分隔符将四句分成四小节。然后用tokens=3提取第三小节,即“举头望明月”了。

delims=和tokens=共用一对双引号,如果单独用双引号,则FOR命令返回的只能是它们之中的一个。因为在第一节说过,FOR是逐一读取命令的,将delims和tokens分开后,FOR只能一次读取一个,不能一次全部读取。

注意:

Tokens常和delims一起使用。

首先,一行内容被delims用分割符号如逗号等分隔成许多小段或小节。

然后,tokens才能提取每行之间对应的这些小段或小节——列。具体看下面例子。

例:提取前面例子文本“a.txt”中每行的第三段内容“ccc”、“kkk”、“ggg”、“考试”。

@echo off

for /f "skip=1 delims=,, tokens=3" %%i in (a.txt) do echo %%i 

pause>nul

注意:为什么kkk不出现呢?

例:如何屏蔽掉文本“a.txt”中的标点符号?

@echo off

for /f "skip=1delims=,, tokens=1-4" %%i in (a.txt) do echo %%i %%j %%k %%l

pause>nul

讲解:

%%i %%j %%k %%l是输出变量,它的个数由tokens后面的(m-n)决定,一般有(n-m+1)个,但不能超过Z。

并且%%后面的字母存在先后顺序,%%a %%b是顺向,倒过来则是逆向的。

代行号的tokens=m*,星号表示m后面的所有剩余的列。

例:

for /f "tokens=*"   %%i in (a.txt) do echo %%i 

讲解:

没有指定具体的列,"tokens=*"将

提取全部列,后面只需一个输出变量%%i。

例:

for /f "tokens=2*"   %%i in (a.txt) do echo %%i %%j

讲解:

"tokens=2*"提取第二列以后的所有字符,星号表示剩余的字符。输出变量%%i对应于2的输入变量,%%j对应于星号的输入变量。

注意:

这里没有使用delisms但却以空格分隔了,是因为FOR默认空格是做分隔符的。

例:屏蔽掉“易经.txt”中的标点符号: 

@echo off

for /f "tokens=1-5 delims=:," %%a in (易经.txt) do echo %%a %%b %%c %%d %%e

pause>nul

讲解:

当delims定义了两个分隔符“:”和“,”时,提取列要用到tokens。

有五个列,所以tokens要定义提取第一列至第五列,即1-5,相应地,后面需要五个输出显示变量%%a %%b %%c %%d %%e。你也可以这样修改,避免过多的变量符号【补充?】

你也可以将最后多余的句号定义为分隔符“delims=:,。”将其屏蔽掉。

转载于:https://www.cnblogs.com/Jian-Zhang/p/6066429.html

import os # 定义绝对路径(根据你的实际情况修改) log_dir = r"D:\jupyter notebook\logs" # 创建目录(如果不存在) if not os.path.exists(log_dir): os.makedirs(log_dir) print(f"已创建日志目录: {log_dir}") else: print(f"使用现有日志目录: {log_dir}") print("\n训练BERT模型...") import tensorflow as tf from transformers import BertTokenizer, TFBertForSequenceClassification from transformers import InputExample, InputFeatures # 确保使用匹配的分词器和模型[^1][^4] model_path = r"D:\jupyter notebook\models" tokenizer = BertTokenizer.from_pretrained(model_path, unk_token="[UNK]") # 显式处理未登录词 # 验证词表一致性 print(f"分词器词表大小: {tokenizer.vocab_size}") # 准备BERT输入(添加安全验证) def convert_examples_to_tfdataset(texts, labels, max_length=100): input_examples = [ InputExample(guid=i, text_a=text, label=label) for i, (text, label) in enumerate(zip(texts, labels)) ] features = [] for ex in input_examples: input_dict = tokenizer.encode_plus( ex.text_a, add_special_tokens=True, max_length=max_length, padding='max_length', truncation=True, return_attention_mask=True, return_token_type_ids=True ) features.append(InputFeatures( input_ids=input_dict['input_ids'], attention_mask=input_dict['attention_mask'], token_type_ids=input_dict['token_type_ids'], label=ex.label )) def gen(): for f in features: # 关键修复:确保token ID在词表范围内[^1][^4] safe_input_ids = [min(token_id, tokenizer.vocab_size - 1) for token_id in f.input_ids] yield ( { 'input_ids': safe_input_ids, 'attention_mask': f.attention_mask, 'token_type_ids': f.token_type_ids }, f.label ) return tf.data.Dataset.from_generator( gen, output_types=( { 'input_ids': tf.int32, 'attention_mask': tf.int32, 'token_type_ids': tf.int32 }, tf.int32 ), output_shapes=( { 'input_ids': tf.TensorShape([max_length]), 'attention_mask': tf.TensorShape([max_length]), 'token_type_ids': tf.TensorShape([max_length]) }, tf.TensorShape([]) ) ) # 创建数据集 train_ds = convert_examples_to_tfdataset(X_train.tolist(), y_train.tolist()) test_ds = convert_examples_to_tfdataset(X_test.tolist(), y_test.tolist()) # 批处理 batch_size = 32 train_ds = train_ds.shuffle(100).batch(batch_size).prefetch(tf.data.AUTOTUNE) test_ds = test_ds.batch(batch_size).prefetch(tf.data.AUTOTUNE) # 构建BERT模型(确保配置一致) bert_model = TFBertForSequenceClassification.from_pretrained( model_path, num_labels=1, from_pt=True # 显式声明使用PyTorch权重[^1] ) # 验证模型词表大小 print(f"模型词表大小: {bert_model.config.vocab_size}") assert tokenizer.vocab_size == bert_model.config.vocab_size, \ "词表大小不匹配!请检查模型文件完整性" # 修复配置不一致 if bert_model.config.vocab_size != tokenizer.vocab_size: bert_model.config.vocab_size = tokenizer.vocab_size print(f"已手动修正模型词表大小为: {tokenizer.vocab_size}") bert_model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=3e-5), loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy'] ) # 安全训练(添加调试回调) print("\n开始训练BERT模型...") bert_history = bert_model.fit( train_ds, validation_data=test_ds, epochs=3, verbose=1, callbacks=[ tf.keras.callbacks.TensorBoard(log_dir='./logs'), tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=1) ] ) # 评估BERT模型 bert_results = bert_model.evaluate(test_ds) print(f"BERT测试准确率: {bert_results[1]:.4f}") 118 bert_history = bert_model.fit( 119 train_ds, 120 validation_data=test_ds, 121 epochs=3, 122 verbose=1, 123 callbacks=[ 124 tf.keras.callbacks.TensorBoard(log_dir='./logs'), 125 tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=1) 126 ] FailedPreconditionError: {{function_node __wrapped__CreateSummaryFileWriter_device_/job:localhost/replica:0/task:0/device:CPU:0}} . is not a directory [Op:CreateSummaryFileWriter] name:
最新发布
06-24
<think>我们面对的问题是:在使用TensorBoard回调函数时,出现`FailedPreconditionError:.isnotadirectory[Op:CreateSummaryFileWriter]`错误。根据引用[1]和引用[2],这个错误是因为TensorFlow尝试将日志写入一个不是有效目录的路径。错误分析:1.错误信息明确指出:当前提供的日志目录路径不是一个目录(可能是文件,或者路径不存在,或者路径是当前目录的根等)。2.在引用[2]中提到,运行TensorBoard时如果不在事件文件的上层目录运行,也会导致类似错误。但这里我们的错误发生在训练过程中,是写日志时的问题。常见原因:-日志目录路径指向了一个文件(而不是目录)。-日志目录路径不存在,且TensorFlow没有自动创建(可能由于权限问题或路径字符串问题)。-日志目录路径是一个空字符串或当前目录的根(例如点号`.`),而当前目录可能不存在或者是文件。解决方案:步骤1:检查日志目录路径确保传递给TensorBoard回调函数的`log_dir`参数是一个有效的目录路径。步骤2:在代码中创建目录在创建TensorBoard回调之前,确保日志目录存在。可以使用`os.makedirs`创建目录。步骤3:避免使用点号`.`作为日志目录如果使用点号`.`(当前目录)作为日志目录,可能会因为当前工作目录的不确定性导致问题。建议明确指定一个目录名(例如`'logs'`)。步骤4:检查路径字符串确保路径字符串没有多余的空格或非法字符。修复代码示例:假设我们原来的代码可能是这样的:```pythonlog_dir="."#当前目录,容易出问题#或者log_dir="logs"但未创建目录tensorboard_callback=tf.keras.callbacks.TensorBoard(log_dir=log_dir)```修复后的代码:```pythonimportosimporttensorflowastf#指定一个明确的日志目录log_dir="logs"#相对路径,会创建在当前工作目录下的logs文件夹#确保目录存在os.makedirs(log_dir,exist_ok=True)#创建TensorBoard回调tensorboard_callback=tf.keras.callbacks.TensorBoard(log_dir=log_dir)#然后在model.fit中使用回调model.fit(...,callbacks=[tensorboard_callback])```如果问题仍然存在,请检查:1.当前工作目录是否可写?可以使用`os.getcwd()`查看当前工作目录。2.路径中是否包含特殊字符?避免使用中文、空格等(引用[1]提到路径包含中文字符可能出错)。另外,引用[2]提到的事件文件路径问题,虽然是在运行TensorBoard时出现的,但也提示我们要注意日志目录的层级结构。确保你指定的日志目录是专门用于存放TensorBoard日志的目录,并且该目录下没有其他文件(或者可以接受混在一起)。如果使用分布式训练,确保所有进程都能访问同一个日志目录,并且该目录位于共享文件系统中。注意事项:-在Windows系统中,路径分隔符使用反斜杠`\`,但为了避免转义问题,建议使用正斜杠`/`或原始字符串(如`r"logs\model"`)。-在Linux系统中,注意目录的权限问题。如果上述方法不能解决问题,请提供更多关于你的日志目录设置的细节。相关问题:1.如何设置TensorBoard回调函数以记录训练指标?2.TensorFlow中如何正确设置分布式训练的日志目录?3.如何解决TensorBoard无法找到日志文件的问题?4.如何在训练过程中实时监控TensorBoard?</think>### 解决 TensorFlow 日志目录导致的 FailedPreconditionError 错误 #### 错误原因分析 根据引用[1][^1],此错误的核心原因是 **TensorFlow 无法在指定路径创建日志目录**。具体表现为: ```bash FailedPreconditionError: . is not a directory [Op:CreateSummaryFileWriter] ``` 主要触发场景: 1. **路径指向文件而非目录**(最常见原因) 2. **目录路径不存在**且未自动创建 3. **路径包含非法字符**(如中文路径在某些系统不兼容) 4. **权限不足**导致无法创建目录 #### 完整修复方案 ```python import os import tensorflow as tf from tensorflow.keras.callbacks import TensorBoard # ===== 关键修复步骤 ===== # 1. 明确指定有效日志目录(避免使用点号'.') log_dir = "training_logs" # 推荐使用明确目录名 # 2. 确保目录存在且可写 os.makedirs(log_dir, exist_ok=True) # 自动创建目录[^1] # 3. 验证路径类型(调试用) print(f"路径类型: {'文件' if os.path.isfile(log_dir) else '目录'}") print(f"路径存在: {os.path.exists(log_dir)}") # ===== 模型配置 ===== model = tf.keras.Sequential([...]) # 你的模型结构 model.compile([...]) # 你的编译配置 # 4. 创建安全的TensorBoard回调 tensorboard_cb = TensorBoard( log_dir=log_dir, # 使用修复后的路径 histogram_freq=1, write_graph=True, write_images=True ) # ===== 安全训练 ===== try: model.fit( x_train, y_train, epochs=10, validation_data=(x_test, y_test), callbacks=[tensorboard_cb] # 包含回调 ) except tf.errors.FailedPreconditionError as e: print(f"训练失败: {e}") print("请检查日志目录权限或磁盘空间") ``` #### 关键修复点详解 1. **避免使用点号`.`作为路径** 错误信息中的 `.` 表示当前目录,但TensorFlow要求明确目录路径: ```python # 错误 ❌ TensorBoard(log_dir='.') # 正确 ✅ TensorBoard(log_dir='training_logs') ``` 2. **目录存在性保障** 使用 `os.makedirs(log_dir, exist_ok=True)` 确保: - 目录不存在时自动创建 - 目录已存在时不会报错[^1] 3. **路径验证技巧** 添加调试代码检查路径属性: ```python # 检查是否为目录 assert os.path.isdir(log_dir), f"{log_dir} 必须是目录" # 检查写入权限 assert os.access(log_dir, os.W_OK), f"无写入权限: {log_dir}" ``` #### 进阶调试技巧 若问题仍未解决,尝试: ```python # 方法1:使用绝对路径避免相对路径歧义 log_dir = os.path.abspath("training_logs") # 方法2:检查文件系统权限 if not os.access(log_dir, os.W_OK): os.chmod(log_dir, 0o755) # 设置写权限 # 方法3:分布式训练特殊处理 if tf.distribute.has_strategy(): # 分布式环境 # 确保所有worker使用相同路径 with tf.device("/cpu:0"): os.makedirs(log_dir, exist_ok=True) ``` #### 错误处理流程 $$ \text{错误检测} \rightarrow \begin{cases} \text{路径存在?} \rightarrow \text{创建目录} \\ \text{是目录?} \rightarrow \text{检查权限} \\ \text{路径合法?} \rightarrow \text{清理非法字符} \end{cases} \rightarrow \text{重试操作} $$ [^1]: 此修复直接解决了引用中提到的核心问题:确保路径是有效的可写目录 [^2]: 参考了事件文件路径层级处理的经验
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值