脚本可用于文件输入,但不适用于stdin

时间:2018-09-28 15:51:19

标签: bash awk

这真让我感到难过。这是我想要做的:

我尝试将文章从newsboat传递到脚本。然后,该脚本应从文章中提取标题和网址。

这是示例文章:

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.

文章通过新闻播报传递了宏:

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

1 个答案:

答案 0 :(得分:2)

在您的脚本中,您假设$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",而不是cat $article
  • 避免使用echo,请使用printf

可以对该脚本进行其他增强,但是很抱歉,我没有时间。


[edit]由于您实际上不需要~/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"