bash - 脚本适用于文件输入,但不适用于标准输入
问题描述
这真的让我很难过。这是我正在尝试做的事情:
我尝试将文章从新闻船传送到脚本。然后,此脚本应从文章中提取标题和网址。
这是一篇示例文章:
Feed: NYT > Home Page
Title: Hit Pause on Brett Kavanaugh
Author: THE EDITORIAL BOARD
Link: https://www.nytimes.com/2018/09/26/opinion/kavanaugh-supreme-court-hearing-delay.html?partner=rss&emc=rss
Date: Thu, 27 Sep 2018 01:58:11 +0200
The integrity of the Supreme Court is at stake.
这篇文章使用来自 newsboat 的宏进行管道传输:
macro R pipe-to "cat | ~/.scripts/newsboat_extract"
这是工作脚本:
#!/bin/bash
cat > ~/newsboat #I do not really need this file, so if I can cut out saving to a file, I would prefer to
title="$(awk -F: '/^Title:/{for(i=2;i<=NF;++i)print $i}' ~/newsboat)"
url="$(awk -F: '/^Link:/{print $2 ":" $3}' ~/newsboat)"
printf '%s\n' "$title" "$url" >> newsboat_result
这提供了预期的输出:
Hit Pause on Brett Kavanaugh
https://www.nytimes.com/2018/09/26/opinion/kavanaugh-supreme-court-hearing-delay.html?partner=rss&emc=rss
我想避免保存到文件中。但是,保存到变量确实 - 无论出于何种原因 - 不起作用:这是不起作用的脚本!
#!/bin/bash
article=$(cat)
title="$(awk -F: '/^Title:/{for(i=2;i<=NF;++i)print $i}' "$article")"
url="$(awk -F: '/^Link:/{print $2 ":" $3}' "$article")"
printf '%s\n' "$title" "$url" >> newsboat_result
输出变成这样:
#empty line
#empty line
我完全不知道为什么脚本会这样。它必须与如何存储变量有关,对吧?
有任何想法吗?- 我在 bash 脚本和 awk 方面还很陌生,因此也感谢有关如何更有效地解决此问题的任何评论。
““““““““““““ “ 解决方案 ” ””””””””””””
这样做了,谢谢!
#!/bin/bash
article=$(cat "${1:--}")
title="$(awk -F: '/^Title:/{for(i=2;i<=NF;++i)print $i}' <<< "$article")"
url="$(awk -F: '/^Link:/{print $2 ":" $3}' <<< "$article")"
printf '%s\n' "$title" "$url" >> newsboat_result
解决方案
在您的脚本中,您假设这$ARTICLE
是一个普通文件,并且您正在对其进行多项操作。首先你用 cat 读取它并将内容存储在 中~/newsboat
,然后你用 awk 再次读取它以提取标题,然后你第三次读取它以提取 URL。
这不适用于标准输入;它只能读取一次。
一个快速的解决方法是处理您在第一次操作中创建的副本:
#!/bin/bash
article=$1
feed_copy=~/newsboat
cat "${article:--}" > "$feed_copy" # Use stdin if parameter is not provided
title="$(awk -F: '/^Title:/ { for(i=2; i<=NF; ++i) print $i }' "$feed_copy")"
url="$(awk -F: '/^Link:/ { print $2 ":" $3 }' "$feed_copy")"
printf '%s\n' "$title" "$url" >> "$feed_copy"
显然,没有经过测试,但这应该可以。
笔记:
- 为环境变量保留大写变量名(这只是一个约定)
- 除非您知道自己在做什么,否则您几乎应该总是引用您的变量(
cat "$article"
, not )cat $article
- 避免
echo
,使用printf
可以对此脚本进行其他增强,但抱歉,我没有时间。
[编辑] 由于您实际上并不需要该~/newsboat
文件,因此这里是遵循 Charles Duffy 建议的更新版本:
#!/bin/bash
feed_copy=$(cat "${1:--}")
title="$(awk -F: '/^Title:/ { for(i=2; i<=NF; ++i) print $i }' <<< "$feed_copy")"
url="$(awk -F: '/^Link:/ {print $2 ":" $3}' <<< "$feed_copy")"
printf '%s\n' "$title" "$url"
推荐阅读
- checkbox - EXTJS:如何确定是否已单击数据网格中的标题复选框
- javascript - NodeJs 上的长 setTimeout 被事件队列忽略
- amazon-elastic-beanstalk - 在 AWS Elastic Beanstalk 中使用 SSM 参数存储
- python - 在 Pandas 列中拆分字符串和数字
- c# - 加载数据网格行详细信息中的wpf数据绑定时如何window.showDialog
- javascript - 如何消除响应列之间的空白?
- javascript - 如何在 Firebase 动态表旁边添加一个按钮
- rust - 有没有办法在 Rust 中的每个函数调用之前和之后注入对用户函数的调用?
- javascript - react-bootstrap-multiselect 在 react-bootstrap 4 中无法正常工作
- python - 如何在keras的Model.fit方法中传递validation_data