在bash循环中写入多个文件时期望做错误

时间:2018-10-25 03:46:59

标签: bash

我正在使用下面的命令使用文件中的行获取多个文件2_intents.txt,3_intents.txt ...等

sh -c "for i in $(seq 2 55); do  head -${i} 55_intents_total.txt > ${i}_intents.txt ; done"

但我收到此错误

sh: 2: Syntax error: word unexpected (expecting "do")

更新:我发现当我将其显式放入bash脚本而不是从命令行使用sh -c

时,它确实会运行的问题

2 个答案:

答案 0 :(得分:0)

tl; dr:您需要对整个表达式加单引号,或者对参数(seq -s ' '使用空格分隔符。

您的代码的较简单版本显示了此问题:

$ bash --noprofile --norc -o xtrace
bash-4.4$ sh -c "for i in $(seq 1 2); do echo $i; done"
++ seq 1 2
+ sh -c 'for i in 1
2; do  echo ; done'
sh: -c: line 1: syntax error near unexpected token `2'
sh: -c: line 1: `2; do  echo ; done'

因此,这等效于运行包含以下内容的shell脚本:

for i in 1
2; do  echo ; done

如果我在外壳中运行内部表达式,它会达到我的期望:

bash-4.4$ for i in $(seq 1 2); do echo $i; done
++ seq 1 2
+ for i in $(seq 1 2)
+ echo 1
1
+ for i in $(seq 1 2)
+ echo 2
2

其原因必须是扩展的顺序:在您的原始代码中,该顺序在设置for循环之前被扩展,但是在上面的最后一个示例中,循环是在 before < / em>扩展序列。不过,我找不到这方面的参考。

答案 1 :(得分:0)

问题在于,在将字符串(命令)传递到sh之前,在 处扩展了命令替换和变量引用。因此,执行的操作等效于:

sh -c "for i in 2
3
4
5
...
54
55; do  head - 55_intents_total.txt > _intents.txt ; done"

...和sh在到达do之前先通过换行来弄乱。即使那不是问题,对${i}的两个引用也都被替换为好,因为$i尚未定义。

最简单的解决方案是将命令用单引号而不是双引号引起来:

sh -c 'for i in $(seq 2 55); do  head -${i} 55_intents_total.txt > ${i}_intents.txt ; done'

或者,您可以对$进行转义,以防止当前shell解释它们:

sh -c "for i in \$(seq 2 55); do  head -\${i} 55_intents_total.txt > \${i}_intents.txt ; done"