【问题标题】:Bash script to shift numbers in txt file用于在 txt 文件中移动数字的 Bash 脚本
【发布时间】:2020-11-04 21:11:35
【问题描述】:

所以我对 bash 脚本很陌生,我在想办法解决我的问题时遇到了问题。

所以我想将三个数字写入“ShiftCodeAssociations.txt”,然后内容如下:

1
2
3

但是,每次我运行此脚本时,我都希望它移动数字,以便将数字从顶部移到底部。

在逐行阅读 while 循环后,我发现了这个 https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ 并想出了以下内容

#!/bin/bash
input="/home/ubuntu/ShiftCodeAssociations.txt"
while IFS= read -r line
do
  if [$line = "1"]
  then
        $line = "2"
  elif [$line = "2"]
  then
        $line = "3"
  else
        $line = "1"
  fi
done < $input

但是,这不起作用,它会输出

AdjustShiftCodes.sh: 5: AdjustShiftCodes.sh: [1: not found
AdjustShiftCodes.sh: 8: AdjustShiftCodes.sh: [1: not found
AdjustShiftCodes.sh: 12: AdjustShiftCodes.sh: 1: not found
AdjustShiftCodes.sh: 5: AdjustShiftCodes.sh: [2: not found
AdjustShiftCodes.sh: 8: AdjustShiftCodes.sh: [2: not found
AdjustShiftCodes.sh: 12: AdjustShiftCodes.sh: 2: not found
AdjustShiftCodes.sh: 5: AdjustShiftCodes.sh: [3: not found
AdjustShiftCodes.sh: 8: AdjustShiftCodes.sh: [3: not found
AdjustShiftCodes.sh: 12: AdjustShiftCodes.sh: 3: not found

有人可以帮我吗,拜托:)

谢谢!

【问题讨论】:

  • [ 不仅仅是语法,它还是一个命令。像任何命令一样,它需要空格将其与其参数分开。
  • 一旦您解决了“shell 脚本对空间敏感”的基本问题,您还需要处理逻辑问题。您不需要在变量分配周围留出空格(就目前而言,您正在调用像 1 这样的命令,而您没有 - line="2" 就是您的意思)。您也没有回显任何输出或以其他方式处理修改后的行。不过要小心;您不能在简单的 shell 脚本中读取和写入同一个文件。如所写,您的代码不能很好地概括处理除 3 之外的任何行数。有更好的方法将第一行移到末尾。
  • 请先将您的脚本粘贴到shellcheck.net,然后尝试实施那里提出的建议。
  • 您能否澄清排序是否对您的问题很重要?您的问题和示例的描述让我想到了命令“sort -u”,它会反转您提供的字符串,就像您非常有效地询问一样。

标签: linux bash shell terminal


【解决方案1】:

sed

sed -i '1{h; d}; $G' ShiftCodeAssociations.txt

GNU awk

gawk -i inplace 'NR == 1 {first = $0; next} 1; END {print first >> FILENAME}' ShiftCodeAssociations.txt

狂欢

f="ShiftCodeAssociations.txt"
mapfile -t lines < "$f"
lines+=("${lines[0]}")
unset 'lines[0]'
printf '%s\n' "${lines[@]}" > "$f"

# The rotation can also be done like this:
#    lines=( "${lines[@]:1}" "${lines[0]}" )

f="ShiftCodeAssociations.txt"
temp=$(mktemp)
while IFS= read -r num; do
    echo "$(( num % 3 + 1 ))"
done < "$f" > "$temp" && mv "$temp" "$f"

【讨论】:

  • 这肯定是一个更优雅的解决方案! (非常好,mapfile 以前从未见过)。
【解决方案2】:

顺便说一句,这个脚本在做什么并不是很清楚:因为它不会输出任何东西。在 if 语句中,您只需将字符串 "1""2""3" 分配给变量 $line(替换与文件行对应的初始值)。

您可以尝试使用命令echo 并将值重定向到文件。

使用正确的语法遵循脚本。

#!/bin/bash
input="/home/ubuntu/ShiftCodeAssociations.txt"
while IFS= read -r line
do
  if [[ "$line" == "1" ]]; then
        line="2"
  elif [[ "$line" == "2" ]]; then
        line="3"
  else
        line="1"
  fi
done < $input

Bash 有点奇怪,因为“空格”的行为与其他更复杂的语言略有不同。例如,在分配变量时,$line = "1" 的形式不起作用,因为 $line 将被插值并被视为命令(后面有一个空格)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2014-08-05
    相关资源
    最近更新 更多