Bash - 编辑文字

时间:2018-05-20 12:37:47

标签: bash shell

我想编辑此文字。

StringTable resource
{
    Entry _strings
    [ 

    //CUSTOM UI
        { String _name = "CCIconChartTip";          String _text = "Icon Chart for Colonial Charter."; }
        { String _name = "CCIconChart";             String _text = "Icon Chart"; }
.
.
.
    ]
}

如果只显示""中的一个单词(或句子),我该如何编写代码? 下面的代码是我的代码,但它们不起作用。

while true
do
    ((string_num++))
    ori_string=$(sed -n '/string_num/p' $path)

    mid=${ori_string%\"} #To cut a line started with " From behind
    ori=${mid##\"} #To cut a line ended with "

    echo "Original : $ori"
    echo "Translate : "
    read -r trans
    if [ "$trans" -eq "p" ] # To skip
    then
        continue
    elif [ "$trans" -eq "q" ] # To quit
    then
        break
    fi
    sed 'string_nums/ori/trans/g' path
done

抱歉我的英语能力差。

输入和输出

$ sh Banished_translator.sh
Enter a file name
NewLimitStringTable.rsc
Skip to b. Quit to q
Original :
Translate :

什么都没有输出。

2 个答案:

答案 0 :(得分:0)

美好的一天,您的代码中存在许多语法错误,以及一些奇怪的逻辑。要验证语法,可以使用https://www.shellcheck.net/

我使用提供的有限信息做到了最好,但这是我对你的剧本的看法:

#!/bin/bash
#
read -p "Enter a file name: " path

# validate file existance
if [ ! -f $path ]
then
    echo "ERROR: file $path does not exist.  Aborting."
    exit 1
fi

# Counter to know which line the script is currently reading
string_num=0
# Number of lines in file $path
numberoflines=$(wc -l $path | awk '{print $1}')

echo ""
echo "Press 'p' or ENTER to pass, 'q' to quit."

# Read line per line up to the last line in the $path file
while [ $string_num -le $numberoflines ]
do
    (( string_num++ ))

    # Read the line number $string_num
    ori_string=$(sed -n "${string_num}p" $path)

    # First section of text enclosed in ""
    ori=$(echo $ori_string | cut -d'"' -f2)
    # Second section of text enclosed in ""
    mid=$(echo $ori_string | cut -d'"' -f4)

    echo ""
    echo "Original: $ori"
    read -p "Translation: " trans

    if [ "$trans" == "p" ] # To skip
    then
        continue
    fi

    if [ "$trans" == "q" ] # To quit
    then
        break
    fi

    # If the $trans value is == $ori, then output the value of $mid
    if [ "$trans" == "$ori" ] && [ "$ori" != "" ]
    then
        echo "    RESULT: $mid"
    fi
done
  • 我添加了一项检查以确保输入文件存在,避免错误。
  • 我删除了while true。到达文件末尾后无需永远查看。
  • 当您比较if语句中的数字时,您使用-eq,-le,-lt,...要比较文字,您需要==!=

无论如何,请尝试并根据需要进行调整。

答案 1 :(得分:0)

我没有密切关注您的代码,但我看到至少有两个以您可能不想要的方式调用sed的实例:

  1. sed -n '/string_num/p' $path

    这将在string_num给出的文件中查找文字字符串$path。您可能需要sed -n "/$string_num/p" "$path"(包含$string_num的打印行)或sed -n "${string_num}p" "$path"(打印行号$string_num)。另请注意引用$path

  2. sed 'string_nums/ori/trans/g' path

    这应该给你一个关于“未终止的s命令”的错误。我猜这里你的意思是sed "${string_num}s/$ori/$trans/g" "$path",但是如果$ori包含被解释为正则表达式符号的字符,或者$trans包含类似的特殊字符,则无效。

  3. 此外,使用-eq的测试应该生成错误,因为-eq用于测试整数的相等性。 [ ... ]中的字符串比较是使用=完成的。

    假设没有嵌套或转义 ",并且所有这些字符串都不会在几行中被分解。

    使用您提供的数据:

    $ grep -oE '"[^"]+"' file
    "CCIconChartTip"
    "Icon Chart for Colonial Charter."
    "CCIconChart"
    "Icon Chart"
    

    表达式"[^"]+"将匹配",后跟至少一个非"字符和另一个"。请注意,这是一个相当简单的匹配,但它适用于您提供的数据。

    进一步假设此输出的每个奇数行都是您引用的“原始”文本,并且您希望从用户读取这些文本的翻译版本并将其替换为原始文件。我们可以创建一个以制表符分隔的对列表:

    $ grep -oE '"[^"]+"' file | paste - -
    "CCIconChartTip"        "Icon Chart for Colonial Charter."
    "CCIconChart"   "Icon Chart"
    

    ...然后阅读以便为用户创建我们的问题:

    exec 3<&1
    grep -oE '"[^"]+"' file |  paste - - |
    while IFS=$'\t' read -r short long; do
        printf 'Original:\t%s (%s)\n' "$long" "$short"
        read -u 3 -rp  'Enter translation (p=pass, q=quit): ' trans
        [ "$trans" = "p" ] && continue
        [ "$trans" = "q" ] && break
    
        sed -i "s/$long/\"$trans\"/" file    # fixme
    done
    

    我们需要在此处使用filedescriptor进行一些操作,以便内部read不会从paste的输出中读取。

    sed遇到与您的代码中相同的问题(如果您更正),因为恰好是正则表达式字符的$long$trans的任何字符都将搞砸了sed的电话。

    如果您找到了一种更好的方法来实际使用翻译人员提供的文本更新原始文件,那么一般方法会有效。

    恕我直言,将原始文件真正提供给作者并让他们用文本编辑器编辑它可能不那么容易出错。