我写了一个简单的脚本来从一堆文件(*.out
)中提取文本,并在开头添加两行,在末尾添加一行。然后,我将提取的文本与另一个文件一起添加以创建一个新文件。脚本在这里。
#!/usr/bin/env bash
#A simple bash script to extract text from *.out and create another file
for f in *.out; do
#In the following line, n is a number which is extracted from the file name
n=$(echo $f | cut -d_ -f6)
t=$((2 * $n ))
#To extract the necessary text/data
grep " B " $f | tail -${t} | awk 'BEGIN {OFS=" ";} {print $1, $4, $5, $6}' | rev | column -t | rev > xyz.xyz
#To add some text as the first, second and last lines.
sed -i '1i -1 2' xyz.xyz
sed -i '1i $molecule' xyz.xyz
echo '$end' >> xyz.xyz
#To combine the extracted info with another file (ea_input.in)
cat xyz.xyz ./input_ea.in > "${f/abc.out/pqr.in}"
done
./script.sh: line 4: (ls file*.out | cut -d_ -f6: syntax error: invalid arithmetic operator (error token is ".out) | cut -d_ -f6")
如何纠正此错误?
答案 0 :(得分:1)
在bash中,当您使用时:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
sess = tf.Session()
order = 5
x = np.zeros(30)
x[10] = 1
y = tf.layers.conv1d(inputs=tf.reshape(x,[1, len(x), 1]),
filters=1,
kernel_size=order,
padding='same')
sess.run(tf.global_variables_initializer())
y_out = sess.run(y)
# get coef
coef = sess.run(tf.all_variables()[-2].value())
print(coef.reshape(order))
它将括号的内容视为算术表达式,返回计算结果,以及使用时:
$(( ... ))
执行括号中的内容并返回输出。
因此,要解决您的问题,只需将第4行替换为:
$( ... )
这将外部双括号替换为单个,并删除了n=$(ls $f | cut -d_ -f6)
周围多余的括号。
答案 1 :(得分:1)
可以通过在括号之间添加空格来避免算术错误。您已经在脚本的其他位置正确使用了var=$((arithmetic expression))
,因此应该很容易理解为什么$( ((ls "$f") | cut -d_ -f6))
需要空格。但是子外壳也是完全多余的。您想要$(ls "$f" | cut -d_ -f6)
。除了ls
在这里没有做任何有用的事情;使用$(echo "$f" | cut -d_ -f6)
。除了外壳可以很容易地(尽管有点笨拙)之外,还可以提取带有参数替换的子字符串。 "${f#*_*_*_*_*_}"
。除非您始终在脚本中使用Awk,否则在Awk中执行此操作(以及执行更多操作)更有意义。
这里是将大多数处理重构为Awk的尝试。
for f in *.out; do
awk 'BEGIN {OFS=" " }
# Extract 6th _-separated field from input filename
FNR==1 { split(FILENAME, f, "_"); t=2*f[6] }
# If input matches regex, add to array b
/ B / { b[++i] = $1 OFS $4 OFS $5 OFS $6 }
# If array size reaches t, start overwriting old values
i==t { i=0; m=t }
END {
# Print two prefix lines
print "$molecule"; print -1, 2;
# Handle array smaller than t
if (!m) m=i
# Print starting from oldest values (index i + 1)
for(j=1; j<=m; j++) {
# Wrap to beginning of array at end
if(i+j > t) i-=t
print b[i+j]; }
print "$end" }' "$f" |
rev | column -t | rev |
cat - ./input_ea.in > "${f/foo.out/bar.in}"
done
还请注意我们如何避免使用临时文件(如果没有Awk重构,这当然也可以避免),以及我们如何注意用双引号引起来的所有文件名变量。
数组b
包含(最多)来自匹配行的最新t
值;我们将它们收集到一个数组中,当到达索引t
时,通过将索引i
包装回到数组的开头,将它们限制为永远不能包含超过t
个值。这种“圆形数组”避免了在内存中保留太多的值,如果输入文件包含许多匹配项,这会使脚本变慢。