コマンドを介してファイルを時系列順にリストし、それを別のコマンドに引数として渡すにはどうすればよいですか?

コマンドを介してファイルを時系列順にリストし、それを別のコマンドに引数として渡すにはどうすればよいですか?

コマンドラインからいくつかのファイルを引数として受け入れるプログラムがあります。逆の順序でリストされたディレクトリ内のすべてのファイルを使用して呼び出したいと思います。

たとえば、

私は逆の順序でディレクトリに次のファイルを持っています

$ ls -tr
 Introduction.pdf  'Object-Oriented Data Model.pdf' 

プログラムを直接実行でき、

myprogram Introduction.pdf  'Object-Oriented Data Model.pdf' 

しかし、別のコマンドでファイルを一覧表示したいと思います。ファイル名の1つにスペースが含まれているため、機能しません。

myprogram $(ls -tr)

ls出力を解析することは良い習慣ではないことを覚えておいてください。私が助けることができるかどうかわかりませんfind

だから私は何ができますか?

ありがとうございます。

答え1

最新バージョンのGNUユーティリティがある場合は、NULLで終わるデータを処理することができます。これにより、データ自体の空白や改行の影響を受けないパイプラインを構築できます。

私のテストツールは次のようなクイックスクリプトです/tmp/args

#!/bin/bash
echo "This is args with $# value(s)"
for f in "$@"; do echo "> $f <"; done

コマンドラインで、次のようにファイルが最後に変更された時刻に基づいてソートされたファイル名の範囲を指定できます。

find -type f -printf "%T@ %p\0" | sort -zn | sed -z 's/^[0-9.]* //' | xargs -0 /tmp/args

このfindコマンドは、各ファイル/パス名の前に最後に変更された日付/時刻の小数秒の表示を追加します。これはsort、最も低いもの(古いもの)から最も高いもの(最新)まで処理されます。sed結果のファイル名のセットを並べ替えて渡すために使用した先行番号を削除しますxargs。ファイル名から先行番号を省略する%pには、に置き換えます。%P./

サンプルデータ

# "c d" contains a space; "e f" contains a newline; "h" has leading whitespace
touch a 'e
f' g ' h ' 'c d' b

結果の例

This is args with 6 value(s)
> ./a <
> ./e
f <
> ./g <
> ./ h  <
> ./c d <
> ./b <

答え2

吹く修正時間でファイルをソートすることはまだ簡単ではありません。したがって、これはzshに基づく必須の答えです。その機能を使用するためにログインシェルでzshに切り替える必要はありません。

ここでは、1つまたは2つの引数を使用するラッパー関数を設定しました。最初の引数は実行するプログラム(たとえばmyprogram)、2番目のオプションの引数はプログラムに渡すファイルを含むディレクトリです。 2番目のパラメータを指定しない場合、デフォルトは現在のディレクトリです。

zeio() {
  # Zsh-based Execute with files In Order
  [ -d "${2:-.}" ] || return
  zsh -c "$1 \"${2:-.}\"/*(.om)"
}

もちろん、名前は必要に応じて指定できます。 2番目の引数(再度デフォルトは現在のディレクトリ)の迅速な完全性チェックの後.、プログラムといくつかの初期引数(引数#1)とディレクトリ(引数#1)を含む単一引用符文字列を使用してzshを呼び出します。 ) — デフォルトは.— 2 つのワイルドカード/グローバル拡張を使用します。「グローバル予選」次の括弧内:

  1. .- 通常のファイルでなければなりません(ディレクトリやシンボリックリンクなどではありません)。
  2. omo-- 結果のリストを変更時順に最新順にソート(ソート)します。

omここで実際の作業をすべて行うのはこのglob修飾子です。

myprog以下は、受け取る引数を順番に表示するために使用されるいくつかの例の実行です。

#!/bin/sh
for arg do
  printf 'Arg: ->%s<-\n' "$arg"
done

go.sh関数を保存するファイルです。残りのディレクトリ構造は次のとおりです。

$ tree .
.
├── dir1
│   ├── 203142
│   ├── 203143
│   └── 203144
├── dir3
│   ├── first\012filename
│   ├── this is 3rd
│   └── this is second
├── dir two
│   ├── 203225
│   ├── 203226
│   └── 203227
├── go.sh
└── myprog

...各サブディレクトリにリストされている順序で3つのファイルセットを作成しました。関数の実行時に同じ順序で表示したいと思います。 dir3の下の最初のファイル名には、treewithと表示される改行文字があります\012。結果:

現在のディレクトリをデフォルト値に設定する動作を示します。

$ zeio ./myprog
Arg: ->./myprog<-
Arg: ->./go.sh<-

一般ファイル名のデモ

$ zeio ./myprog dir1
Arg: ->dir1/203142<-
Arg: ->dir1/203143<-
Arg: ->dir1/203144<-

ディレクトリにスペースがあります

$ zeio ./myprog "dir two"
Arg: ->dir two/203225<-
Arg: ->dir two/203226<-
Arg: ->dir two/203227<-

ファイル名にスペースがあります

$ zeio ./myprog dir3
Arg: ->dir3/first
filename<-
Arg: ->dir3/this is second<-
Arg: ->dir3/this is 3rd<-

答え3

(IFS=$'\n'; set -f; your_program $(ls -tr))

ファイル名に改行文字が含まれていないとします。

例:

% touch 'a   b'
% touch 'c d'
% touch '*'
% (IFS=$'\n'; set -f; printf '%s\n' $(ls -tr))
e    f
a   b
c d
*

文字列をサポートしていない$'...'標準シェルのバリエーション:

(IFS='
' ; set -f; your_program $(ls -tr))

ファイル名に改行文字が含まれていても機能するシンプルなPythonラッパーです。ただ使用してくださいthis_wrapper your_program *

#! /usr/bin/python
import os
import sys

sys.argv[2:] = sorted(sys.argv[2:], key=os.path.getmtime)
os.execvp(sys.argv[1], sys.argv[1:])

関連情報