繁体   English   中英

在同一行 Bash 中回显多个变量

[英]Echo multiple variables in same line Bash

我想在同一行上回显两个变量。
我想将 2015-03-04.01.Abhi_Ram.txt 存储在变量 FILENAME 中,将 10 存储在变量 COUNT 中并同时回显它们。

示例.txt

2015-03-04.01.Abhi_Ram.txt 10
2015-03-04.02.Abhi_Ram.txt 70

下面是我想出的代码:

for line in `hadoop fs -cat sample.txt`
do

VAR="${line}"
FILENAME=`echo ${VAR}|awk '{print $1}'`
COUNT=`echo ${VAR}|awk '{print $2}'`
COUNT_DT=`date "+%Y-%m-%d %H:%M:%S"`
echo db"|"Abhi_Ram"|"record_count"|"${FILENAME}"||"${COUNT}"||"${COUNT_DT} >> output.txt
done

I want the output as:

db|Abhi_Ram|record_count|2015-03-04.01.Abhi_Ram.txt||10||时间戳 db|Abhi_Ram|record_count|2015-03-04.02.Abhi_Ram.txt||70||时间戳

I'm getting the output as:

db|Abhi_Ram|record_count|2015-03-04.01.Abhi_Ram.txt||||时间戳
db|Abhi_Ram|record_count|10||||时间戳
db|Abhi_Ram|record_count|2015-03-04.02.Abhi_Ram.txt||||时间戳
db|Abhi_Ram|record_count|70||||时间戳

有人可以指出我缺少什么吗?

考虑:

while read filename count
do
    count_dt=$(date "+%Y-%m-%d %H:%M:%S")
    echo "db|Abhi_Ram|record_count|${filename}||${count}||${count_dt}"
done <sample.txt >>output.txt

这将生成文件:

$ cat output.txt 
db|Abhi_Ram|record_count|2015-03-04.01.Abhi_Ram.json||10||2015-08-10 14:42:39
db|Abhi_Ram|record_count|2015-03-04.02.Abhi_Ram.json||70||2015-08-10 14:42:39

笔记:

  1. 最佳做法是对 shell 变量使用小写或混合大小写。 系统使用大写变量,您不希望意外覆盖一个。

  2. echo语句中的许多双引号是不必要的。 整个输出字符串可以在一个双引号字符串中。

  3. 如果你想一次读取一个文件,使用while read ... done <inputfile结构更安全。 read语句还允许我们轻松定义filenamecount变量。

  4. 对于命令替换,许多人更喜欢$(...)形式而不是反引号形式。 这是因为 (a) $(...)使命令替换的开头和结尾在视觉上不同,(b) $(...)形式嵌套良好,以及 (c) 并非所有字体都清楚地显示反引号不同于普通的蜱虫。 (谢谢切普纳。)

  5. 为提高效率,重定向到output.txt已移至循环末尾。 这样,文件只打开和关闭一次。 (感谢查尔斯·达菲。)

  6. 除非您需要用每个单独的条目更新count_dt ,否则它可以放置在循环之前,并且每次处理sample.txt时只设置一次。 如果您有最新版本的 bash(没有 Mac OSX),那么count_dt赋值可以替换(感谢 Charles Duffy)用原生 bash 语句(不需要脱壳):

     printf -v count_dt '%(%Y-%m-%d %H:%M:%S)T'

John1024 已经解释了如何正确执行此操作; 我想看看为什么原始版本不起作用。 基本问题是for循环遍历words ,而不是遍历行。 该文件每行有两个词(一个文件名和一个计数),因此它每行运行两次循环。 要看到这一点,请尝试:

for line in `hadoop fs -cat sample.txt`
do
    echo "$line"
done

...它会打印如下内容:

2015-03-04.01.Abhi_Ram.txt
10
2015-03-04.02.Abhi_Ram.txt
70

……这根本不是你想要的。 它还有一些其他令人不快的怪癖,比如如果输入文件包含单词“*”,它会在当前目录中插入一个文件名列表。

while read ... done <file方法是在 shell 脚本中迭代行的正确方法。 它恰好也能够将每一行拆分为字段而不必弄乱awk (在这种情况下, read filename count就可以了)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM