trコマンドは$()で使用され、変数に保存された場合は効果がありません。

trコマンドは$()で使用され、変数に保存された場合は効果がありません。

CLI で実行する場合:

curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n"

すると、予想どおり、ページから へのサニタイズされたリンクのリストがSTDOUT、それぞれ新しい行に表示されていきます。

ただし、それを変数に保存し、echoそれをから実行しようとすると、次のようになりますscript.sh

PAGE_LINKS=$(curl time.com | sed -n 's/.*href="\([^"]*\).*/\1/p' | tr " " "\n")
echo $PAGE_LINKS

すべてのリンクをスペースで区切って 1 行に表示します。tr無視されたかのようになります。

私は次のようなことをいろいろ試しました

HREFS=$(tr " " "\n" < "{PAGE_LINKS}")
echo $HREFS

しかし、その後file too longエラーが発生します。何か提案はありますか?

答え1

bash構造のマニュアルページによると$(command):

Bash は、コマンドを実行し、コマンド置換をコマンドの標準出力に置き換えて展開を実行します。末尾の改行は削除されます。埋め込まれた改行は削除されませんが、単語分割中に削除される可能性があります。

trこれは問題ではありませんが、末尾bashに改行がある場合はそれを削除し、単語分割中に他の改行を削除します。これはドキュメントに記載されている動作です。

ほとんどの場所でこの動作が望ましいと思います。ファイル名のリストを含むファイルがある場合は、次のようになります。

for FILENAME in $(cat somefile)
do
     ...
done

somefileファイル名のリストを反復します。改行によってファイル名として使用する単語のリストが台無しになったり、for-do-done ループが台無しになったりするのは望ましくありません。

答え2

問題は ではなくtr、変数展開をどのように出力しているかにあります。

echo $PAGE_LINKS

変数の展開を引用します:

echo "$PAGE_LINKS"

それ以外の場合、拡張は の値 (デフォルトではスペース、タブ、改行) に従って単語分割されIFS、パス名拡張 ( *?[]) が実行されます。

あなたの場合、単語の分割が行われ、改行で区切られた各要素が個別に取得され、最終的にスペースで区切られたエンティティとして表示されます。引用符を使用すると、単語の分割 (およびパス名の展開) が防止されるため、展開全体が単一のエンティティとして取得されます。

関連情報