我正在编写一个shell脚本,该脚本读取文本文件并基于它们创建JSON键值对。 key
是文件名,而value
是文件的随机行。
麻烦是当我在全局变量key
中将value
与data
串联时。
当我运行下面的代码时:
data='{'
for file in $(ls _params)
do
key=${file%.txt}
f_line=$(($$%100))
value=$(sed "${f_line}q;d" "./_params/$file")
# assembles key-value pairs
data=$data\"$key\":\""value"\",
done
data=${data%?} # removes last comma
data="$data}"
echo $data
我的输出是:{"firstName":"value","lastName":"value"}
但是将字符串"value"
更改为变量$value
,如下所示:
data='{'
for file in $(ls _params)
do
key=${file%.txt}
f_line=$(($$%100))
value=$(sed "${f_line}q;d" "./_params/$file")
# assembles key-value pairs
data=$data\"$key\":\"$value\",
done
data=${data%?} # removes last comma
data="$data}"
echo $data
输出混乱:"}"lastName":"Adailee
。
我希望在$data
变量中存储以下内容:{"firstName":"Bettye","lastName":"Allison"}
注意:我的bash版本是4.3.48。
注意:在我的档案_params
中,我有两个文件firstName.txt
和lastName.txt
,每行都有随机名称。
答案 0 :(得分:2)
$value
显然以回车符(\r
,U + 000D)结尾。结果,当您打印它时,光标移回到该行的开头,随后的字符从第一列开始打印,覆盖之前的内容。 (当然,这并不影响字符的实际顺序;在打印时,它只会令人困惑地显示。)
要解决此问题,您可以编写
value="${value%$'\r'}"
删除尾随回车。
答案 1 :(得分:2)
正如@ruakh所建议的,具体问题是您的输入文件。以下是重现您的问题并进行验证的步骤:
我创建了两个firstNames.txt文件,其中A B C D重复了100次:
$ cat ABCD
A
B
C
D
$ for _ in $(seq 1 100); do cat ABCD >> _params/firstName.txt
,然后与W X Y Z类似,用于lastNames.txt。然后我运行了您的脚本:
$ bash q.sh
{"firstName":"A","lastName":"W"
但是,如果我使用unix2dos
(来自dos2unix软件包)将其转换为\ r \ n行尾。
$ unix2dos _params/firstName.txt
unix2dos: converting file _params/firstName.txt to DOS format...
$ unix2dos _params/lastName.txt
unix2dos: converting file _params/lastName.txt to DOS format...
$ bash q.sh
"}"lastName":"W
因此,您可能可以使用dos2unix
来修复输入文件(或打开vim
并先执行:set ft=unix
然后执行:x
)。
但是我想让您了解其他三件事。
ls
,而是改用1 这是我对改进脚本的建议(一旦您在输入中修复了换行符):
#!/bin/bash
data='{'
sep=""
for file in _params/*
do
key=${file%.txt}
file_length=$(wc -l < ${file})
f_line=$(( (RANDOM % file_length) + 1 ))
value=$(sed "${f_line}q;d" "${file}")
# assembles key-value pairs
data="${data}${sep} \"$key\":\"$value\""
sep=","
done
data="${data} }"
echo $data