首页 > 解决方案 > 脚本适用于文件输入,但不适用于标准输入

问题描述

这真的让我很难过。这是我正在尝试做的事情:

我尝试将文章从新闻船传送到脚本。然后,此脚本应从文章中提取标题和网址。

这是一篇示例文章:

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

标签: bashawk

解决方案


在您的脚本中,您假设这$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"

推荐阅读