如何解决当jq输出空字符串时,bash readarray -t数组分配出现问题
#!/bin/bash
a_string="string"
readarray -t a <<<"$a_string"
echo "${a[@]}"
echo "${#a[@]}"
# read empty string into array
emptystring=""
readarray -t b <<<"$emptystring"
echo "${b[@]}"
echo "${#b[@]}"
# and Now - empty array
c=()
echo "${c[@]}"
echo "${#c[@]}"
和输出
string
1
1
0
因此,使用readarray -t
将一个空字符串读入bash数组将显示数组长度为1。只有真正的空数组的长度为0。
我的问题-为什么会发生?
以我为例-这是脚本的一部分-执行API调用,获取JSON并应用jq过滤器:
URL_list_json=$(curl -s --request GET "$curl_request" --header "Authorization: Bearer ${token}")
readarray -t URL_names <<<"$(echo "$URL_list_json" | jq -r '.[].Body.monitors[].name')"
[
{
"Header": {
"Region": "dc1","Tenant": "tenant1","Stage": "test"
},"Body": {
"monitors": []
}
}
]
[
{
"Header": {
"Region": "dc2","Tenant": "tenant2","Stage": "qa"
},"Body": {
"monitors": [
{
"enabled": true,"entityId": "TEST-674BA97E74FC74AA","name": "production.example.com"
},{
"enabled": false,"entityId": "TEST-3E2D23438A973D1E","name": "test.example.com"
}
]
}
}
]
我需要检查URL_names
数组是否为空。如果不为空,则遍历内容。如果为空-表示jq没有返回任何结果-白色以记录并继续。
如果我使用if ((${#URL_names[@]}))
作为检查数组是否为空的方法,即使该数组仅来自jq调用中的空字符串,它也将返回1,因此此逻辑将失败。
有什么其他方法可以处理上述情况?
我可以将jq过滤器的输出分配给一个字符串,然后使用 if 语句检查该字符串是否为空以及是否为非空,然后将该字符串分配给数组,但这引入了其他元素。通过这种方法,我可以完全跳过使用数组-我希望仅使用数组来完成此任务。
谢谢
解决方法
为什么会这样?
因为它读一行。来自bash manual here document:
[n]
[...]结果以单个字符串的形式提供,在其标准输入(或如果指定n的情况下为文件描述符n)中以附加换行符的形式提供给命令。
因为有换行符,所以public class MainActivity extends AppCompatActivity {
ImageView videoImage ;
EditText editTextVideoTitle;
EditText editTextVideoDescription;
Button btnPostButton;
Button btnCancelButton;
private String mVideoPath;
private String mVideoThumb;
String strVideoTitle;
String strVideoDescription;
boolean videoPosted;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_vid_with_desc);
editTextVideoTitle = (EditText) findViewById(R.id.videoTitle);
editTextVideoDescription = (EditText) findViewById(R.id.videoDescription);
btnPostButton = (Button) findViewById(R.id.postButton);
btnCancelButton = (Button) findViewById(R.id.cancelButton);;
mVideoPath = getIntent().getStringExtra("path");
mVideoThumb = getIntent().getStringExtra("thumb");
btnPostButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
videoPosted = postVideo();
if (videoPosted) {
Toast.makeText(getApplicationContext(),"Your video posted successfully.",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),"Error in posting video,please try again.",Toast.LENGTH_SHORT).show();
}
}
});
}
public boolean postVideo() {
Log.i("Info","PostVidWithDescActivity : postVideo : Start");
String strUserId = "";
String strReservedfield = "";
boolean isVideoPosted = false;
sharedPreferences = this.getSharedPreferences("com.app.rapid",Context.MODE_PRIVATE);
strVideoTitle = editTextVideoTitle.getText().toString();
strVideoDescription = editTextVideoDescription.getText().toString();
try {
strUserId = sharedPreferences.getString("userId","");
strReservedfield = "ReservedField";
outputData = new PostToServerAsyncTask().execute(mVideoPath,strUserId,strVideoTitle,strVideoDescription,strReservedfield).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
if (null != outputData && outputData.equalsIgnoreCase("200")) {
isVideoPosted = true;
} else{
isVideoPosted = false;
}
return isVideoPosted;
}
private class PostToServerAsyncTask extends AsyncTask<String,Void,String> {
private String content;
private String Error = null;
private int serverResponseCode;
Context context;
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("inputBuilder","PostToServerAsyncTask : onPreExecute Start") ;
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.setIndeterminate(false);
//progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
progressDialog.setCancelable(false);
progressDialog.show();
Log.i("inputBuilder","PostToServerAsyncTask : onPreExecute End") ;
}
@Override
protected String doInBackground(String... inputData) {
/*
File upload code
*/
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Some string";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("inputBuilder","PostToServerAsyncTask : onPostExecute Start") ;
if (null != progressDialog && progressDialog.isShowing()) {
progressDialog.dismiss();
}
Log.i("inputBuilder","PostToServerAsyncTask : onPostExecute End") ;
}
}
}
读取一个空行。您可以这样做:
readarray
注意:
-
readarray -t b < <(printf "%s" "$emptystring")
不是首选。在posix shell中执行echo "$var"
,在bash中执行printf "%s" "$var"
(并且您不必担心多余的换行符)。 -
<<<"$var"
总是看起来很奇怪-<<<"$(...)"
无论如何都必须分配一个子shell。做<<<
。 - 您要执行的操作:
< <(...)
- 如果要检查数组是否为空,请在
readarray -t URL_names < <(<<<"$URL_list_json" jq -r '.[].Body.monitors[].name')
中进行检查。 I see ex.jq
,然后检查退出状态。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。