head
修正されたスクリプト(コマンド?)を〜/ .bashrcに追加します。手動で入力するかワイルドカードから派生するか、stdinで提供するかを期待どおりに処理します。ただし、引数を指定するのを忘れた場合、headj
端末は中断され、Ctrl-Cを使用して再起動できません。
echo
これは私のコードです(デバッグ目的でいくつかの呼び出しを含む)。
headj(){
echo "script makes it this far without arguments"
IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
echo "but but crashes before getting here"
#
for i in ${input[@]}; do
echo -e "███████████████████████████████████████████████████████████████████████████████"
echo -e "headj $i start"
head -50 "$i"
done
}
次のように動作します。
$ headj list1
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
$ headj list*
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ ls -1 li* | headj
script makes it this far without arguments
but not this far
███████████████████████████████████████████████████████████████████████████████
headj list1 start
a
b
███████████████████████████████████████████████████████████████████████████████
headj list2 start
c
d
$ headj
script makes it this far without arguments
それがかかっているところです。
読み取り入力を試しましたinput=( ${@:-$(</dev/stdin)} )
が、同じエラーが発生しました。エラーを処理するには、スクリプトの先頭にこのコードを追加してください。
if [ -z ${*:+x} ]; then
echo "headj requires at least one argument"
return
fi
もっと良い方法がありますか?また、このような質問には必ず検索すべきキーワードがありますか?
答え1
引数や間違ったパイプなしで実行していて、関数のstdinにファイル名を書きたくないと仮定すると(そうする理由)、stdinがttyであることを確認するチェックを追加します。
headj() {
local files=()
if [ "$#" -gt 0 ]; then
files=("$@")
elif ! tty >/dev/null; then
readarray -t files
else
echo "Will not read filenames from a tty!" >&2
fi
for file in "${files[@]}"; do
echo "do something with $file..."
done
}
したがって、これはうまくいきます。
$ ls *.txt |headj
do something with test.txt...
しかし、これは以下について文句を言います。
$ headj
Will not read filenames from a tty!
使用するコマンドはread
ファイル名をスペースに分割するため、そうしません。したがって、パラメータの数と上記の配列の条件は異なります。改行readarray
で区切られた項目のリストを読む必要があります。これはパイプで接続されたls
ときにfind
生成されるものですが、もちろん、改行を含むファイル名が機能しないことを意味します。
(少しトリッキーかもしれませんが、パラメータや操作では複数の単語を生成する必要があるため使用しません。ただし、そうしないでください。使用すると、意図が単一の"$@"
文字列を変換することをより明確にすることができます。)<<<
<<< "$*"
^Cが機能しない理由については繰り返すことができず、関数がそうするようになっているようではありません。
答え2
私はbashrcに機能を追加する方法を学びました。ありがとうございます。問題を解決するには、これを試してください。
headj(){
ARG=${1? Error. Please, provide the input file. Example: headj filename}
#echo "script makes it this far without arguments"
IFS=" " read -r -a input <<< "${@:-$(</dev/stdin)}"
#echo "but but crashes before getting here"
#
for i in ${input[@]}; do
echo -e ""`enter code here`
echo -e "headj $i start"
head -50 "$i"
done}
$headj
バッシュ: 1: エラー。入力ファイルを提供してください。例: headj ファイル名
パイプの例
$echo "It works for me." > answer.txt
$ cat answer.txt
これは私にとって効果的です。
$headj answer.txt | awk '{print $_}'
headj レスポンス.txt 開始
これは私にとって効果的です。
headj answer.txt | awk '{print $_}' | sed 's/me./me. It should work for you too./g'
headj レスポンス.txt 開始
これは私にとって効果的です。それはあなたにも効果があります。