PowerShell HereDoc空白与制表符问题及长文本替代方案
问题本质
PowerShell的Here-String(HereDoc)语法有硬性规则:结束标记("@或'@)必须位于行的第一列,前面不能有任何空格、制表符或其他空白字符。一旦给结束标记加了前置空白,PowerShell会无法识别Here-String的结束位置,要么继续将后续代码当成字符串内容解析,要么直接抛出语法错误——这就是你遇到的$text2和$Menu1示例报错的原因。
可行解决办法
根据你既要优化代码缩进格式,又要保留内容空格/制表符的需求,有两种常用方案:
方案1:变量赋值缩进,结束标记顶格(保留内容原格式)
这种方案既让代码整体缩进整齐,又能完全保留Here-String里的原始格式,是最直接的做法:
function random_ascii () { $text = @" _ ____ ____ ___ ___ _ _ _ _ _ / \ / ___| / ___|_ _|_ _| / \ _ __| |_ / \ _ __ ___| |__ (_)_ _____ / _ \ \___ \| | | | | | / _ \ | '__| __| / _ \ | '__/ __| '_ \| \ \ / / _ \ / ___ \ ___) | |___ | | | | / ___ \| | | |_ / ___ \| | | (__| | | | |\ V / __/ /_/ \_\____/ \____|___|___| /_/ \_\_| \__| /_/ \_\_| \___|_| |_|_| \_/ \___| "@ Write-Output $text } random_ascii
这里$text = @"可以跟着函数体缩进,而结束标记"@严格顶格,PowerShell能正确识别Here-String的边界,代码格式和内容格式都能兼顾。
方案2:结束标记随代码缩进,用字符串处理移除内容统一前置空白
如果你希望结束标记也跟着代码缩进(比如和变量赋值对齐),可以先保留带统一缩进的内容,再用正则表达式移除每一行的前置空白:
function random_ascii () { $rawText = @' _ ____ ____ ___ ___ _ _ _ _ _ / \ / ___| / ___|_ _|_ _| / \ _ __| |_ / \ _ __ ___| |__ (_)_ _____ / _ \ \___ \| | | | | | / _ \ | '__| __| / _ \ | '__/ __| '_ \| \ \ / / _ \ / ___ \ ___) | |___ | | | | / ___ \| | | |_ / ___ \| | | (__| | | | |\ V / __/ /_/ \_\____/ \____|___|___| /_/ \_\_| \__| /_/ \_\_| \___|_| |_|_| \_/ \___| '@ # 移除每一行开头的4个空格(根据你的实际缩进量调整) $text = $rawText -replace '^ ','' Write-Output $text } random_ascii
这种方案适合内容本身的前置空白是统一格式的场景,既让代码缩进整齐,又能得到干净的内容输出。
针对你的$Menu1示例修正
原代码报错是因为'@前面有空格,导致PowerShell没识别到Here-String结束,把$Menu2当成了字符串的一部分。修正后:
$Menu1 = @' Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. '@ $Menu2 = "Hello World"
把'@顶格写,$Menu2就能正常执行了。
总结
PowerShell Here-String的结束标记必须顶格是语法硬规则,无法直接绕过。要兼顾代码格式和内容格式,要么采用变量赋值缩进+结束标记顶格的方案,要么用字符串处理移除内容统一缩进+结束标记随代码对齐的方案。
内容的提问来源于stack exchange,提问作者Ichigo Kurosaki

