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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反转文本文件中的任何行(执行rev命令)相关的知识,希望对你有一定的参考价值。

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

a b c

输出将是:

c b

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

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[@]}"打印它时,它会添加一个新空间..为什么?

答案

如果你使用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[@]}" $'
' > file

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

另一答案

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,所以我们可以这样做,同时向后读取行,从而摆脱整个第二个数组,但是你想知道,什么在你的方法中不起作用,本来应该是如果我进一步重构了代码,那就模糊了。

另一答案

使用纯

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

输出:

cba

以上是关于反转文本文件中的任何行(执行rev命令)的主要内容,如果未能解决你的问题,请参考以下文章

Linux-文本工具

将命令行参数和文本文件传递给程序

如何反转文件中的行顺序?

使用macOS中的命令行向文件添加(Spotlight)注释

是否可以动态编译和执行 C# 代码片段?

分享几个有趣的Linux命令