bash脚本中奇怪/意外的字符串替换

问题描述

我有一个bash脚本,可以根据其内容重命名某些文本文件。具有以下内容文件,例如应该重命名2020-05-11_Chess-com.txt

[Site "Chess.com"]
[Date "2020-05-11"]
[White "Computer 6"]
[Result "0-1"]
[Termination " won by checkmate"]
... More content ...

在下面找到我当前正在使用的脚本的模型:

#!/bin/bash 
site=$(sed -n '1p' < "$1" | cut -d ' ' -f2 | tr -d '"]' | tr ' .' '-')
datum=$(sed -n '2s/[^0-9-]*\([0-9-]*\)[^0-9-]*/\1/p' < "$1")

echo "${datum}_${site}"  # 2020-05-11_Chess-com
echo "${datum}_${site}".txt  # .txt-05-11_Chess-com
echo "$datum"_"${site}".txt  # .txt-05-11_Chess-com

最后两行中的字符串替换结果对我来说是完全出乎意料的,我发现很难找到有关脚本异常行为的任何解释。

尽管我没有太大帮助,但是我发现,如果我将site=$(...)替换为site="Chess-com",则会得到预期的结果2020-05-11_Chess-com.txt

解决方法

您的脚本可以很好地处理您提供的示例,但它要求输入内容完全规则。也许切换到实际检查文件是否为预期格式的文件。

#!/bin/sh
awk '/\[Site / { site=$1; gsub(/[]"\r]/,"",site) }
    /\[Date / { datum=$2; gsub(/[]"\r]/,datum) }
    END { print datum "_" site ".txt" }' "$1"

这也可以消除所有DOS回车,我想这可能是问题的根源。

,

您的代码看起来不错,但我建议您进行一些改进

site=$(sed -n 's/\[Site "\(.*\)"\]/\1/p' "$1")
date=$(sed -n 's/\[Date "\(.*\)"\]/\1/p' "$1")
echo "${date}_$site.txt"

或者这样

read -d\n site date trash <<< $(sed 's|^.*"\(.*\)".*$|\1|g' "$1")
printf '%s_%s.txt' $date $site

或者这样

sed -n 'N;s|.*Site.*"\(.*\)".*"\(.*\)".*|\2_\1.txt|p' "$1"