首页 > 解决方案 > 带有 content.replace 的嵌套 foreach() 循环未按预期设置内容(或添加内容)

问题描述

我有以下带有两个嵌套 foreach 循环的 Powershell 脚本。该脚本应该从一个简单的 SQL 文件中获取内容,为表名添加前缀并根据前缀/学生名写出新的 SQL 文件。

$content = Get-Content "[PATH_FILE].sql"
$students = @('18adadam','18bebert','18dadavi')
# $students = Get-Content "[PATH_FILE].txt"
$tables = @('image','post','user')

foreach ($student in $students) {
  foreach ($table in $tables) {
    $tablename = $student + '_' + $table
    'Table name: ' + $tablename
    $content = $content.Replace("TABLE ``$table``","TABLE ``$tablename``") 
  } 
  $content | Set-Content ("$student.sql")
  'Content: '+ $content
}

文件按预期创建:

内部循环中变量 $tablename 的输出很好:

表名:18adadam_image

表名:18adadam_post

表名:18adadam_user

表名:18bebert_image

表名:18bebert_post

表名:18bebert_user

表名:18dadavi_image

表名:18dadavi_post

表名:18dadavi_user

但是写入文件(和控制台)的内容仅包含第一个学生(18adadam)的更正表:

--
-- Table structure for table `image`
--

CREATE TABLE `18adadam_image` (
  `id` int(11) NOT NULL,
  `filename` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `postId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Table structure for table `post`
--

CREATE TABLE `18adadam_post` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `userId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

最初,行内容替换行如下所示:

$content = $content.Replace("TABLE ``$table``","TABLE ``$student" + "_" + "$table``")

而且我担心连接会以某种方式与编写内容有关,因此我将其更改为表名的单个变量。

$tablename = $student + '_' + $table
$content = $content.Replace("TABLE ``$table``","TABLE ``$tablename``") 

我添加了

'Table name: ' + $tablename

'Content: '+ $content

作为简单的调试行来查看脚本中每个点发生了什么。

我还尝试查看将输出更改为单个文件是否会改变任何内容:

  $content | Add-Content ("[PATH_FILE]_2.sql")

正如预期的那样,它所做的只是为 18adadam 创建了一个具有正确 sql 的文件,重复了 3 次。

标签: powershell

解决方案


第二个$content.Replace(找不到原始值,因为它在 $content 中更改。
将更改保存到不同的变量。

## Q:\Test\2018\10\11\SO_52758908.ps1
$content = Get-Content ".\template.sql"
$students = @('18adadam','18bebert','18dadavi')
# $students = Get-Content "[PATH_FILE].txt"
$tables = @('image','post','user')

foreach ($student in $students) {
  $Newcontent = $content
  foreach ($table in $tables) {
    $tablename = "{0}_{1}" -f $student,$table
    'Table name: ' + $tablename
    $Newcontent = $Newcontent.Replace("TABLE ``$table``","TABLE ``$tablename``")
  }
  $Newcontent | Set-Content ("$student.sql")
  'Content: '
  $Newcontent
}

推荐阅读