【问题标题】:Shell script to Translate the find third word separated by tab in a line用于翻译在一行中由制表符分隔的查找第三个单词的 Shell 脚本
【发布时间】:2013-09-29 01:49:29
【问题描述】:

有人可以帮我写一个脚本来翻译每行中的第三个单词,单词之间用制表符分隔。

示例输入:

Hello how Are You
Iam Fine how about

样本输出:

Hello how Ziv You
Iam Fine sld about

每行中的第三个单词应该翻译成使用:tr '[abcdefghijklmnopqrstuvqxyz]' '[zyxwvutsrqponmlkjihgfedcba]'

【问题讨论】:

  • 看起来那里有错字 - 第二个 q 而不是 w - 还是故意的?

标签: regex perl shell unix


【解决方案1】:
perl -F'\t' -lane '$F[3] =~ tr/ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyz/ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba/ ; print "@F"' Filename

【讨论】:

  • $F[2]。这是要更改的第三个字,perl数组是从零开始的。
【解决方案2】:

类似这样的AWK脚本

#!/usr/bin/awk -f
BEGIN{
    IFS="\t"                                        #input field separator as tab
    CHARSET = "abcdefghijklmnopqrstuvwxyz"      
}

{
    rep_str=""                                      #replacement string
    # loop in through each char of third word
    for(i=1;i<=length($3);i++){
        char = substr($3,i,1)
        loc = index(CHARSET,tolower(char))

        #check to see if the character is actually an alphabet
        if(loc>0){

            #get the reverse location of char in the CHARSET                               
            rep_char = substr(CHARSET,27-loc,1)    

            #change the replacement character to upper case if the original char is uppercase
            if(char~/[A-Z]/){
                rep_char = toupper(rep_char)   
            }
        }else{
            rep_char = char
        }
        rep_str=rep_str rep_char                       #final replacement sting formed by concatenation of replaced char rep_char 
    }
    $3 = rep_str                                           
    print $0    
}

【讨论】:

    【解决方案3】:

    只是 bash:

    #!/bin/bash
    while read -ra A; do
        printf "%s\t%s" "${A[0]}" "${A[1]}"
        printf "\t%s" "$(echo "${A[2]}" | tr '[ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyz]' '[ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba]')" "${A[@]:3}"
        echo
    done
    

    运行方式:

    bash script.sh < input_file
    

    输出:

    Hello   how     Aiv     You
    Iam     Fine    slw     about
    

    如果您将\t 更改为空格():

    Hello how Ziv You
    Iam Fine slw about
    

    另一个版本:

    #!/bin/bash
    F=({A..Z} {a..z}) R=({Z..A} {z..a})
    while read -ra A; do
        printf "%s\t%s" "${A[0]}" "${A[1]}"
        printf "\t%s" "$(IFS=''; echo "${A[2]}" | tr "[${F[*]}]" "[${R[*]}]")" "${A[@]:3}"
        echo
    done
    

    【讨论】:

    • Getng 错误:bash script.sh <<<' script.sh: command substitution: line 1: tr '[ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyz]' '[ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba "${A[2]}"' You Iam Finescript.sh:命令替换:第 1 行:意外标记附近的语法错误 &lt;&lt;&lt;' script.sh: command substitution: line 1: tr '[ABCDEFGHIJKLMNOPQRSTUVQXYZabcdefghijklmnopqrstuvqxyz]''[ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba]'
    • 问题中的错字似乎已经渗透到您和所有其他答案中。而不是在tr 表达式中拼出整个字母表,我想我会这样做而不是为了可靠性:fwd=$(eval "echo {a..z} {A..Z}"); rev=$(eval "echo {z..a} {Z..A}") 然后 tr 表达式可以是tr "[${fwd// /}]" "[${rev// /}]")
    • @DigitalTrauma 这可能是尽管您不再需要使用 eval 例如rev=$(echo {a..z} {A..Z})。另外我更喜欢使用数组。请参阅我的编辑。我记得在制作这个脚本时尝试过{a..z}(因为我不想手动输入 A-Z a-z),但我不确定当时它是如何不起作用的。哦,好吧。
    • 是的,数组方法肯定更优雅,但我认为您需要最近的 bash。它确实适用于 4.2.25,但不适用于 3.00.15。
    • @DigitalTrauma Brace 扩展适用于 3.0,并且阵列至少从 2.05b 开始就已经存在。
    【解决方案4】:

    鉴于以下情况:

    [somedude@dev7 ~]# cat so.txt 
    Hello   how Are You
    Iam Fine    how about
    [somedude@dev7 ~]# 
    

    我会跑:

    [somedude@dev7 ~]# cat so.sh 
    #!/bin/bash
    
    _INPUT="Hello how Are You
    Iam Fine how about"
    
    # read each line from config file
    while read -r l 
    do
    
      _GET_THIRD_WORD=$(echo $l | awk '{print $3}')
    
      echo $_GET_THIRD_WORD | sed -i "s,$_GET_THIRD_WORD,SOMETHINGTOTRANSLATEWITH," 
    
    done < so.txt
    [somedude@dev7 ~]# 
    

    这会将您翻译的每一行回显到标准输出。

    希望这会有所帮助!

    【讨论】:

      【解决方案5】:

      这很笨拙,但可以完成工作(在 bash shell 中)。它在整个输入文件上使用 sed 的 y 音译运算符。这通过进程替换传递给 awk 和存储在数组中的第三个字段。然后,awk 循环遍历原始文件并将第三个字段的每个实例替换为音译值。

      awk -F'\t'  -v OFS='\t' 'NR == FNR{a[NR]=$3; next};{$3=a[FNR]; print}' \
      <(sed -e 'y/abcdefghijklmnopqrstuvqxyz/zyxwvutsrqponmlkjihgfedcba/' \
      -e 'y/ABCDEFGHIJKLMNOPQRSTUVQXYZ/ZYXWVUTSRQPONMLKJIHGFEDCBA/' file) file
      

      【讨论】:

      • 出现错误:awk -F'\t' -v OFS='\t' 'NR == FNR{a[NR]=$3;下一个};{$3=a[FNR]; print}' \ > -e 'y/ABCDEFGHIJKLMNOPQRSTUVQXYZ/ZYXWVUTSRQPONMLKJIHGFEDCBA/'MPACTS) MPACTS awk:第 1 行附近的语法错误 awk:在第 1 行附近退出 sed 命令:乱码:y/ABCDEFGHIJKLMNOPQRSTUVQXYZ/ZYXWVUTSRQPONMLKJIHGFEDCBA/MPACTS
      猜你喜欢
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 2015-02-26
      • 2012-12-10
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多