【问题标题】:No such file or directory on bash assignmentbash 分配中没有这样的文件或目录
【发布时间】:2015-04-23 08:35:02
【问题描述】:

我正在尝试编写一个脚本,将“测试”文件中的每一行保存在变量 line1、line2 等中......

x=$(cat test | wc -l)   #here i have how many lines
i="1"

while [ "$i" -lt "$x" ]
do
line$i=$(sed '$iq;d' test)   #i try to get the number $i line one by one
i=$[$i+1]                              
done

你能帮帮我吗?

谢谢!

【问题讨论】:

  • 在您运行它的目录中是否有一个名为 test 的文件?
  • 是的,当我输入纳米测试时:2015-01-29/ 2015-01-30/ 2015-01-31/ 2015-02-01/ 2015-02-02/ 2015-02- 03/ 2015-02-04/ 2015-02-05/ 2015-02-06/
  • line$1 很奇怪。尝试重命名此变量。
  • 我可以帮助你:mapfile -t lines < test。您将拥有一个漂亮的数组lines,其中的字段包含文件的行。打印第三行:printf '%s\n' "${lines[2]}"(是的,赋值从字段 0 开始,但可以使用 -O 选项更改)。
  • $[$i+1] 表示法已过时;请改用$(($i+1))

标签: bash variables sed while-loop variable-assignment


【解决方案1】:

要将文件test 的每一行读入一个名为lines 的数组中,请使用:

mapfile -t lines <test

示例

考虑这个文件:

$ cat test
dogs and cats
lions and tigers
bears

执行这条语句:

$ mapfile -t lines <test

我们现在可以使用declare -p 看到lines 的值:

$ declare -p lines
declare -a lines2='([0]="dogs and cats" [1]="lions and tigers" [2]="bears")'

文件test 的每一行现在都是数组lines 的一个元素,我们可以通过数字访问它们:

$ echo "${lines[0]}"
dogs and cats

【讨论】:

  • 哈哈现在你会得到我的+1:)
【解决方案2】:

lines$i 应该是 lines[$i](或 google eval),但您可能完全错误,您应该用 awk 编写它,例如:

awk '{lines[NR] = $0} END{print NR; for (i=1;i<=NR;i++) print i, lines[i]}' test

【讨论】:

    【解决方案3】:

    让我们利用available tooling 看看有什么问题:

    $ shellcheck linereader
    In linereader line 1:
    x=$(cat test | wc -l)   #here i have how many lines
    ^-- SC2148: Shebang (#!) missing. Assuming Bash.
            ^-- SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
    
    
    In linereader line 6:
    line$i=$(sed '$iq;d' test)   #i try to get the number $i line one by one
    ^-- SC1067: For indirection, use (associative) arrays or 'read "var$n" <<< "value"'
    ^-- SC2034: line appears unused. Verify it or export it.
                 ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.
    
    
    In linereader line 7:
    i=$[$i+1]
      ^-- SC2007: Use $((..)) instead of deprecated $[..]
    

    这是一个好的开始:

    #!/bin/bash
    # 1. Shebang added
    # 2. Redirection for reading files as suggested (stylistic)
    x=$(wc -l < test)   #here i have how many lines
    i="1"
    
    while [ "$i" -lt "$x" ]
    do
      # 3. Using arrays as suggested
      # 4. Using double quotes for sed as suggested
      # Additionally, use ${i} so we reference $i and not $iq
      line[$i]=$(sed "${i}q;d" test)   #i try to get the number $i line one by one
    
      # 5. Use $((..)) as suggested (stylistic)  
      i=$((i+1))
    done
    
    # Print a line to show that it works:
    echo "Line #2 is ${line[2]}"
    

    现在让我们试试吧:

    $ cat test
    foo
    bar
    baz
    $ ./linereader
    Line #2 is bar
    

    我们也可以使用mapfile 更轻松地完成此操作(并且在 O(n) 时间内):

    #!/bin/bash
    mapfile line < test
    echo "Line #2 (zero-based index 1) is: ${line[1]}"
    

    【讨论】:

    • mapfile 是你的朋友。
    猜你喜欢
    • 2016-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多