web-dev-qa-db-ja.com

エコーを使用して1行に1つのファイルを印刷する

echoを使用してファイル/ディレクトリのリストを1行に1つずつ印刷するにはどうすればよいですか?

スペースを改行で置き換えることはできますが、ファイル名にスペースが含まれている場合は機能しません。

$ echo small*jpg
small1.jpg small2.jpg small photo 1.jpg small photo 2.jpg

$ echo small*jpg | tr ' ' '\n'
small1.jpg
small2.jpg
small
photo
1.jpg
small
photo
2.jpg

ls -d1ですが、echoを使用することもできますか?

5
EmmaV

echoを使用して任意のデータを出力することはできません。代わりにprintfを使用してください これは、壊れたechoユーティリティをPOSIXで置き換えてテキストを出力します。

printf '%s\n' small*jpg

あなたも行うことができます:

printf '%s\0' small*jpg

リストをNUL区切りのレコードで出力するには(後処理ができるように、たとえばGNU xargs -r0を使用して;改行文字はスペースまたはファイル名)。

POSIXがprintfを思い付く前に、kshはprintを置き換えるechoユーティリティをすでに持っていました。 zshはそれをコピーし、-lオプションを追加して、1行に1つずつ引数を出力します。

print -rl -- small*jpg

ksh93は、printのような印刷のためにprintf-fオプションを追加しました。 zshによってもコピーされますが、他のksh実装ではコピーされません。

print -f '%s\n' -- small*jpg

引数が指定されていない場合でも、これらすべてが空の行を印刷することに注意してください。よりよいprintlnは、次のように関数として記述できます。

println() {
  [ "$#" -eq 0 ] || printf '%s\n' "$@"
}

zsh内:

println() print -rC1 -- "$@"
15

echoは、引数として受け取る文字列を区切るためにスペースのみを使用します。

あなたの質問にはタグが付けられている bash ですので、bashhelp echoは次のように言っています(強調は私のものです):

標準出力に、ARGを表示します単一の空白文字で区切られたとそれに続く改行。

他の実装のドキュメントにも同様のステートメントがあります。例えば。 echo from coreutils のそれは、GNU/Linuxで見つかる可能性があります。

echoは、指定された各文字列を標準出力に書き込みます。各文字列と最後の文字列の後の改行の間にはスペースを入れます。

echoでファイル名を別々の行に出力したい場合は、それらを単一の文字列としてフィードする必要があります。

$ touch "small1.jpg" "small2.jpg" "small photo 1.jpg" "small photo 2.jpg"
$ (set -- small*.jpg; IFS='
'; echo "$*")
small1.jpg
small2.jpg
small photo 1.jpg
small photo 2.jpg

ここでは、*特殊パラメーターの動作を利用しています。二重引用符内では、位置パラメーターの配列の要素が連結された単一のWordに展開されます。 IFS変数の最初の文字(改行に設定)を使用します。

(...)構文は、サブシェル環境でコマンドを実行するために使用されます。通常、メインのシェルには影響を与えたくありません。

ただし、 Stéphane's answer で説明されているように、すべてのechoの制限が引き続き適用されるため、このシナリオでの使用はお勧めできません。

3
fra-san