Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash echo在连接的字符串中间输出文本_Bash_Echo_Kubuntu - Fatal编程技术网

Bash echo在连接的字符串中间输出文本

Bash echo在连接的字符串中间输出文本,bash,echo,kubuntu,Bash,Echo,Kubuntu,序言: 所以我有一个项目,我需要在一堆文件上运行一个转换工具。转换有多个步骤,可能需要一段时间。由于这些文件不一定在同一目录中,因此我创建了一个文本文件,其中包含要转换的文件名: <filenames.txt> /home/me/Documents/file1.txt /home/me/Documents/file2.txt /home/me/Documents/file3.txt “FORMAT_B Filename”是回音文本,出现在附加文本“form_B.xml”之前 我查

序言: 所以我有一个项目,我需要在一堆文件上运行一个转换工具。转换有多个步骤,可能需要一段时间。由于这些文件不一定在同一目录中,因此我创建了一个文本文件,其中包含要转换的文件名:

<filenames.txt>

/home/me/Documents/file1.txt
/home/me/Documents/file2.txt
/home/me/Documents/file3.txt
“FORMAT_B Filename”是回音文本,出现在附加文本“form_B.xml”之前

我查看了dirname、basename、echo和tr的手册页,但没有发现任何看起来会导致我看到的内容的内容。我试着在谷歌上四处看看,但我不确定我问的问题是否正确(“变量前的bash echo文本”?)

<>问题:<强>为什么我的回音把回音文本放在变量的中间?< /强>

(可能的相关问题:“我做的事情是否完全错了?”)


Edit:我接受了fortea的答案,因为它让我了解了我不了解的变量,并从命令中获得了输出。也就是说,dogbane和Jonathan Leffler展示了更好的方法来做我正在做的事情。

问题在于变量的声明:

formatb_dir= dirname $some_file | tr '\n' "/"
formatb_file= basename $some_file ".xml" | tr '\n' "_"
formatb=$formatb_dir$formatb_file"form_b.xml\n"
尝试一个新行:
echo$formatb_dir
:它不包含任何内容,因为在“=”后面有一个空格。然后bash读取
dirname$somefile |tr'\n'/“
,并执行此命令。创建formatb_文件时也是如此,但这次的命令是basename。(这是在“FORMAT_B Filename:”之前显示的内容)。 然后正确创建formatb,但$formatb_dir和$formatb_file为空,因此$formatb将只包含
“form_b.xml\n”
。 然后回显“FORMAT_B Filename:”。 然后回显$formatb,它将输出“form_b.xml”

因此,您应该使用以下内容:

Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file1.txt
/home/me/Documents/file1.txt_FORMAT_B Filename:
form_b.xml


Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file2.txt
/home/me/Documents/file2.txt_FORMAT_B Filename:
form_b.xml


Begin FORMAT_A to FORMAT_B conversion...
FORMAT_A Filename:
/home/me/Documents/file3.txt
/home/me/Documents/file3.txt_FORMAT_B Filename:
form_b.xml
formatb_dir=$(dirname $some_file | tr '\n' "/")
formatb_file=$(basename $some_file ".xml" | tr '\n' "_")
formatb=$formatb_dir$formatb_file"form_b.xml\n"

阅读这是因为您正在使用
tr
并删除
\n
字符

与其使用
tr
,为什么不简单地将字符串连接在一起呢

formatb_dir="$(dirname ${some_file})"
formatb_file="$(basename ${some_file})"
formatb="${formatb_dir}/${formatb_file}_form_b.xml"
echo "FORMAT_B Filename: $formatb"

问题是,在以奇怪的方式设置环境的情况下,您正在运行诸如
dirname
basename
之类的命令,而不是捕获输出。也就是说,如果您运行:

env_var=some_value commandname arg1 arg2
程序
commandname
运行时,环境变量
$env_var
设置为
some_value
(仅适用于此命令)。在代码中,您编写了:

formatb_dir= dirname $some_file | tr '\n' "/"
这与我给出的例子是同构的。它运行命令
dirname
,将环境变量
formatb_dir
设置为空字符串(并且
dirname
完全忽略此项),然后将
dirname
的输出发送到
tr
,并将
tr
的输出发送到标准输出

  • shell中的指定周围没有空格
  • 使用
    $(…)
    捕获输出
  • 不要在文件名中嵌入换行符;这会让生活变成地狱
我不会费心将
dirname
输出末尾的换行符映射为斜杠,或者将
basename
输出末尾的换行符映射为下划线。可以在生成的名称中添加斜杠和下划线

固定的:

cat filenames.txt |
while read some_file
do
    echo
    echo "Begin FORMAT_A to FORMAT_B conversion..."
    echo "FORMAT_A Filename:"
    echo $some_file
    formatb_dir=$(dirname "$some_file")
    formatb_file=$(basename "$some_file" ".xml")
    formatb="${formatb_dir}/${formatb_file}_form_b.xml"
    echo "FORMAT_B Filename:"
    echo $formatb
done
formatb
的赋值使用
${varname}
两次以保持一致性;大括号仅在
${formatb_file}
扩展中需要

cat filenames.txt |
while read some_file
do
    echo
    echo "Begin FORMAT_A to FORMAT_B conversion..."
    echo "FORMAT_A Filename:"
    echo $some_file
    formatb_dir=$(dirname "$some_file")
    formatb_file=$(basename "$some_file" ".xml")
    formatb="${formatb_dir}/${formatb_file}_form_b.xml"
    echo "FORMAT_B Filename:"
    echo $formatb
done