INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
head -1
最初のコマンドが成功した場合にのみ2番目のcommand()を実行したいと思います。このコマンドをどのように改善できますか?
答え1
この試み:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
xargs
このフラグを渡すと、標準入力()から1つ以上の項目を読み取ったときにのみ実行されます-r
。basename
head -1
head -1
実行されますが、出力は表示もキャプチャもされません。
または、ユーザーにエラー出力が表示されないようにするには、stderrストリームにリダイレクトls
できます。ls
/dev/null
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
また、周囲に引用符を追加したことに注意してください$MY_DIR
。これにより、スペースが含まれても$MY_DIR
コマンドは失敗しません。
bashなどの最新のシェルを使用している場合は、$( )
バックティックの代わりにキャプチャシェルを使用する必要があります。変数スタイルの変更も考慮する必要があります。通常、スクリプトで変数名をすべて大文字にすることは避けるべきです。このスタイルは通常、保持変数と環境変数用に予約されています。
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
答え2
パイプラインでは、すべてのコマンドが順番に起動して実行されるのではなく、同時に起動して実行されます。したがって、出力をどこかに保存する必要があります。
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
ファイル名に改行文字が含まれていないとします。また、xargs
空白文字、一重引用符、二重引用符、バックスラッシュに関する問題も発生します。引用符のない変数は、スペース、タブ、およびワイルドカードに問題があることを意味します。忘れるということは--
〜を意味する-
。
文字の制限なしで最も古いファイルのデフォルト名を取得するにはzsh
(制限されたコマンドパラメータサイズの問題も回避します):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
一致するものがない場合、コマンドは失敗し、スクリプトは中断されます。次のようにすることもできます。
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
この場合、first_file_name
一致するものがある場合は配列に1つの要素が含まれ、一致するものがない場合は0が含まれます。これにより、次のことができます。
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
答え3
ディレクトリで最近変更されたファイルを見つけます。
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
使用法:latest [directory/path/ [.extension]]
basename
呼び出しの代わりにパラメーター拡張を使用してください。
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
以下を含むディレクトリ:
foo.xml bar.xml baz.xml newest.xml
base_fn変数の内容は次のとおりです。newest
お客様のリクエストの目的に合わせて正しく使用するには、次の手順を実行します。
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
ls
編集:質問を確認した後、問題のコマンドが次を探していることに気づきました。最も古いディレクトリ内のファイル。この同じ機能はに名前を変更でき、oldest
同じ[[ $file -ot $oldest ]] && oldest=$file
効果を達成する必要があります。混乱させて申し訳ありません。
注目すべき重要な点は、どんな人間の状況でもlsの出力を絶対に解析してはならないということです。いいえ。
答え4
ここで最良の選択は次のとおりです。
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
ファイルが存在しない場合、lsの戻りコードは2であり、ファイルが存在する場合は戻りコードは0です。