我尝试编写一个代码来旋转文本文件中的每一行。例如,给出下一行:
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[@]}"
打印它时,它会添加一个新的空格.. 为什么
答案 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)
答案 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
。