反转文本文件中的任何行(执行rev命令)

时间:2018-03-04 16:57:15

标签: bash shell scripting

我尝试编写一个代码来旋转文本文件中的每一行。例如,给出下一行:

  

a b c

输出将是:

  

c b a

此脚本只作为参数获取一个参数 - 文本文件的名称。另外,我想这样做会对额外的空间有所帮助。即,给出下一行:

  

a b c

输出将是:

  

c b a

注释:输出将位于同名的新文件中,后缀为.rotate

我的代码:

#!/bin/bash

name_of_file=$1

first_step=1

while read line; do
    length_of_line=`echo -n "${line}" | wc -c`
    rotate_line=()
    index_of_line=0
    index_of_rotate=$(( length_of_line - 1 ))
        while (( ${index_of_line} < ${length_of_line} )); do
        rotate_line[${index_of_rotate}]="${line[@]:${index_of_line}:1}"
        let index_of_line++
        let index_of_rotate--
        done

        if (( ${first_step} == 1 )); then
            echo "${rotate_line[@]}" > $1.rotate1
            first_step=0
        else
            echo "${rotate_line[@]}" >> $1.rotate1
        fi
done < ${name_of_file}

问题:
我不知道为什么,但是,考虑到这一行:

  

a b c

输出是:

  

c b a

从哪里获得额外的空间?

评论:当我逐个字母地检查旋转数组时,它没问题(没有额外的空格) - 但是,当我用"${rotate_line[@]}"打印它时,它会添加一个新的空格.. 为什么

3 个答案:

答案 0 :(得分:2)

echo ${rotate_line[@]}在数组的每个元素之间放置一个分隔符。

while read line; do
    // get rid of old-fashioned backticks, we're sick of explaining.
    length_of_line=$(echo -n "${line}" | wc -c)
    rotate_line=()
    index_of_line=0
    index_of_rotate=$(( length_of_line - 1 ))
    while (( ${index_of_line} < ${length_of_line} ));
    do
        rotate_line[${index_of_rotate}]="${line[@]:${index_of_line}:1}"
        let index_of_line++
        let index_of_rotate--
    done
    // output characterwise
    for i in $(seq 0 $((length_of_line - 1)))
    do
        // deactivated file-in and out for easy debugging 
        echo -n "${rotate_line[i]}" # >> $1.rotate1
    done
    // for multiple lines, we need an echo here:
    echo
done # < ${name_of_file}

在这种调试友好的方式中,我们可以回显单行或做

cat file | nih-rev.sh > file.rotate1 

快速测试可以快速获得答案。

由于我们通过char输出数组char,我们可以这样做,同时向后读取行,从而摆脱整个第二个数组,但是你想知道,什么在你的方法中没有用,哪个如果我进一步重构代码,那本来就会被模糊。

答案 1 :(得分:0)

使用纯

x='abc'
for ((i=${#x}; i>0; i--)); do echo -n ${x:$i:1}; done

输出:

cba

答案 2 :(得分:0)

如果您使用declare -p rotate_line,您将看到数组实际上包含预期值(没有额外的空格):

declare -a rotate_line='([0]="c" [1]=" " [2]="b" [3]=" " [4]="a")'

但是,在您的代码中,您使用echo "${rotate_line[@]}" > file将数组打印到文件中。这会扩展为echo <item1> <item2> ...echo的默认行为是输出以空格分隔的参数。

一些可能的解决方法:

(IFS=; echo "${rotate_line[*]}") > file
printf '%s' "${rotate_line[@]}" $'\n' > file

您的代码还有其他一些问题,例如while read line。这可能会删除前导和尾随空格,它会破坏反斜杠。请改用while IFS= read -r line