Linux Can';t使用变量扩展名在bash循环中分配适当的文件名

Linux Can';t使用变量扩展名在bash循环中分配适当的文件名,linux,bash,loops,Linux,Bash,Loops,我对这个问题束手无策。 我使用循环将每个文件上的命令迭代到特定目录中。当使用文件的原始名称生成新文件时,使用变量扩展名,只有在变量之前没有文本时才有效。我有这个密码: for f in temp/temp_orfs/* ; do wc -l $f > ${f}_temp gawk '{print $1}' ${f}_temp > temp/temp_orfs/num_${f}_text done ${f}_temp ---> exists num_${f}_t

我对这个问题束手无策。 我使用循环将每个文件上的命令迭代到特定目录中。当使用文件的原始名称生成新文件时,使用变量扩展名,只有在变量之前没有文本时才有效。我有这个密码:

for f in temp/temp_orfs/* ; do
    wc -l $f > ${f}_temp
    gawk '{print $1}' ${f}_temp > temp/temp_orfs/num_${f}_text
done

${f}_temp ---> exists
num_${f}_text --> doesn't exists 

我做错了什么?

f
包含
temp/temp\u orfs
前缀,而不仅仅是目录中的文件名。假设
f
扩展为
temp/temp_orfs/foo
;然后

  • ${f}\u temp
    扩展为
    temp/temp\u orfs/foo\u temp
  • temp/temp\u orfs/num\u${f}\text
    扩展为
    temp/temp\u orfs/num\u temp/temp\u orfs/foo\u text

您需要的是基名称:

for f in temp/temp_orfs/*; do
    bf=${f##*/}
    wc -l "$bf" | gawk '{print $1}' > "temp/temp_orfs/num_${bf}_text"
done
或者,您可以简单地先更改目录:

cd temp/temp_orfs
for f in *; do
    wc -l "$f" | gawk '{print $1}' > "temp/temp_orfs/num_${f}_text"
(无论哪种方式,临时文件都不是必需的,但如果您确实需要它,请务必注意它的名称,以便知道它是在哪里创建的。)


awk
可能没有必要。您可以使用输入重定向使
wc
输出只是一个行计数,尽管结果的格式可能略有不同,这取决于您使用的
wc
实现:

# GNU wc
$ wc -l < some_some_file
21

# BSD wc
$ wc -l < some_small_file
      21
#GNU wc
$wc-l
f
包含
temp/temp\u orfs
前缀,而不仅仅是目录中的文件名。假设
f
扩展为
temp/temp_orfs/foo
;然后

  • ${f}\u temp
    扩展为
    temp/temp\u orfs/foo\u temp
  • temp/temp\u orfs/num\u${f}\text
    扩展为
    temp/temp\u orfs/num\u temp/temp\u orfs/foo\u text

您需要的是基名称:

for f in temp/temp_orfs/*; do
    bf=${f##*/}
    wc -l "$bf" | gawk '{print $1}' > "temp/temp_orfs/num_${bf}_text"
done
或者,您可以简单地先更改目录:

cd temp/temp_orfs
for f in *; do
    wc -l "$f" | gawk '{print $1}' > "temp/temp_orfs/num_${f}_text"
(无论哪种方式,临时文件都不是必需的,但如果您确实需要它,请务必注意它的名称,以便知道它是在哪里创建的。)


awk
可能没有必要。您可以使用输入重定向使
wc
输出只是一个行计数,尽管结果的格式可能略有不同,这取决于您使用的
wc
实现:

# GNU wc
$ wc -l < some_some_file
21

# BSD wc
$ wc -l < some_small_file
      21
#GNU wc
$wc-l
谢谢,这真的很有帮助。因此,为了澄清:如果文件夹只是“temp/”而不是“temp/temp_orfs”,那么在定义变量“$bf”时,我只需要编写bf=${f#*/}?
匹配最短前缀<代码>最长的。基本上,您希望删除路径中最后一个
/
之前的所有内容。(您无法匹配特定数量的组件,因此,例如,
${f###*/}
不会删除前3个目录。)
wc-l“$f”| gawk'{print$1}
=
wc-l
@EdMorton从概念上讲,是的。但是,使用
awk
会从行计数中删除前导空格,因此在不知道以后如何使用
num_${f}\u text
的情况下,我不想在答案中引入这样的格式更改。(但无论使用什么文件,几乎可以肯定地通过最小的调整来应对这种变化。)@EdMorton GNU
wc
yes,BSD
wc
no。(不过,OP可能使用GNU实现。)谢谢,这真的很有帮助。因此,为了澄清:如果文件夹只是“temp/”而不是“temp/temp_orfs”,那么在定义变量“$bf”时,我只需要编写bf=${f#*/}?
匹配最短前缀<代码>最长的。基本上,您希望删除路径中最后一个
/
之前的所有内容。(您无法匹配特定数量的组件,因此,例如,
${f###*/}
不会删除前3个目录。)
wc-l“$f”| gawk'{print$1}
=
wc-l
@EdMorton从概念上讲,是的。但是,使用
awk
会从行计数中删除前导空格,因此在不知道以后如何使用
num_${f}\u text
的情况下,我不想在答案中引入这样的格式更改。(但无论使用什么文件,几乎可以肯定地用最小的调整来应对这种变化。)@EdMorton GNU
wc
yes,BSD
wc
no。(不过,OP可能使用GNU实现。)